问题标签 [god-object]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
7 回答
1497 浏览

debugging - 处理神物

我在一个中等规模的团队中工作,并且经常遇到这些令人痛苦的大类文件。我的第一个倾向是用刀去攻击他们,但这通常只会让事情变得更糟,让我陷入糟糕的心态。

例如,假设您刚刚获得了一个 Windows 服务来处理。现在这个服务有一个错误,你需要弄清楚这个服务做了什么,然后才能有任何修复它的希望。你打开服务,发现有人决定只使用一个文件来处理所有事情。开始方法在那里,停止方法,定时器,所有的处理和功能。我说的是数千行代码。一百行代码以下的方法很少见。

现在假设你不能重写整个类并且这些神类只是不断弹出,处理它们的最好方法是什么?你从哪里开始?你首先尝试完成什么?你如何处理这种事情而不是只想得到所有的刺伤。

如果你有一些策略来控制你的脾气,那也是受欢迎的。

到目前为止的提示:

  1. 建立测试覆盖率
  2. 代码折叠
  3. 重组现有方法
  4. 记录发现的行为
  5. 以渐进式改进为目标

编辑:

Charles Conway 推荐了一个非常有帮助的播客。关联

Michael Feathers(播客中的那个人)从一个前提开始,他们不敢简单地将项目从源代码控制中取出,直接使用它,然后丢弃更改。我可以说我对此感到内疚。

他基本上是说拿走你想了解更多的项目,然后开始把它拆开。发现它的依赖关系,然后打破它们。跟随它走过它所到之处。

很棒的提示 使用在别处使用的大类并让它实现一个空接口。然后使用该类获取代码并让它实例化接口。这将为您提供代码中该大型类的所有依赖项的完整列表。

0 投票
4 回答
1362 浏览

asp.net-mvc - 上帝控制器 - 如何防止它们?

在我一直从事的一些 MVC 项目中,很明显有一些有问题的控制器已经有机地成长为上帝类——如果你愿意的话,每个半神都在自己的领域中。

这个问题可能更像是“什么去哪里”,但我认为这是一个关于 SRP(单一责任原则)、DRY(不要重复自己)和保持简洁、“敏捷”的重要问题——而且我没有足够的经验(使用这种模式和一般设计)来了解这一点。

在一个项目中,我们有一个 NutritionController。随着时间的推移,它逐渐包含了这些操作(许多都有各自的 GET、POST 和 DELETE 方法):

然后我们有一个 ExerciseController,它将包含许多类似的操作,例如搜索和收藏操作。是否应该将这些重构为它们自己的控制器,使其成为类似的东西?

在我看来,如果您将它们分解为单独的控制器,您将在某种程度上增加一个难以置信的大依赖来处理您需要的信息。或者,您将拥有一个完全通用的处理应用程序,该应用程序将非常难以处理,因为您必须跳过这么多圈才能获得所需的效果(在 M、V 或 C 级别)。

我在想这个错误的方式?例如,我是否应该有一个通用的收藏夹对象,然后让控制器决定将它扔到哪个视图?

*抱歉拼出首字母缩略词 - 我这样做是为了以防其他人遇到这个问题并且对这些东西是什么一无所知

编辑: 我执行的所有逻辑都在服务层中处理。例如,控制器会将“新”FoodItem 发送到服务。如果它已经存在,或者它有错误,该服务会将它冒泡回控制器。

0 投票
4 回答
1445 浏览

design-patterns - 哪个更邪恶:不必要的单例或上帝对象?

情况是这样的:我有一堂课做得太多了。它主要用于访问配置信息,但它也有数据库连接。它是作为单例实现的,因此这也使单元测试变得困难,因为大多数代码都与它紧密耦合。这更成问题,因为它创建了一个导入时依赖项(我们在 Python 中这样做),这意味着某些模块必须按特定顺序导入。理想情况下,我想将其分为两个类并使其成为非单例。

幸运的是,我的雇主已经意识到这种测试是好的,并且如果它使代码更具可测试性,他愿意允许我进行这样的更改。但是,我怀疑他们是否愿意让我在上面花费太多时间。我宁愿逐步解决这个问题,也不愿过于激进。

所以,我在这里看到三个选择:

  1. 将配置对象分解为(单例)配置对象和(非单例)数据库对象。这至少可以让我将数据库作为导入时依赖项删除。
  2. 使配置对象成为非单例并将其传递给需要它的对象。我觉得这更好地满足了我们的短期需求,但我认为这需要更多的时间。
  3. 做一些我没有想到的你在回答中建议的事情。:-)

那我该怎么办?

0 投票
6 回答
1744 浏览

oop - 上帝对象 - 减少与“主”对象的耦合

我有一个名为 Parameters 的对象,它在调用树中从一个方法到另一个方法被扔掉,跨越包边界。它有大约五十个状态变量。每种方法都可能使用一个或两个变量来控制其输出。

我认为这是一个坏主意,因为我无法轻易看到一个方法需要运行什么,甚至如果模块 Y 的参数组合与我当前的模块完全无关,甚至可能发生什么。

有什么好的技术可以减少与这个上帝对象的耦合,或者理想地消除它?

来电者会这样做:

0 投票
1 回答
879 浏览

.net - 如何利用 IObservable/IObserver 摆脱我的“上帝对象”?

在我目前正在处理的系统中,我有许多组件被定义为接口和基类。系统的每个部分都有一些特定的点,它们与系统的其他部分交互。

例如,数据准备组件准备了一些数据,这些数据最终需要进入数据处理部分,通信组件需要查询不同组件的状态以中继到外部等。

目前,我使用“上帝对象”或对系统不同部分有深入了解的对象将系统的这些部分粘合在一起。它在这里注册事件并将结果传送给那里的方法,在这里创建一个回调方法并在那里返回该方法的结果,并通过多线程队列传递许多请求以进行处理,因为它“知道”某些操作已经在 STA 线程等上运行

虽然它很方便,但让我担心的是,这种类型非常了解系统中其他人的设计方式。我更喜欢一个更通用的集线器,它可以提供可以公开事件或方法或回调或可以使用这些的实例。

我已经看到更多关于反应式框架的 IObservable/IObserver 功能的信息,并且这些功能正在被纳入 .NET 4.0(我相信)。

我可以利用这种模式来帮助替换我的“上帝对象”吗?我该怎么做呢?是否有任何资源可以将此模式用于此特定目的?

0 投票
2 回答
649 浏览

c# - 以不会成为“上帝对象”的方式设计一个类

我正在设计一个允许我在图形上绘制一些功能的应用程序。每个函数都将从我将传递给这个图形类的一组点中绘制出来。

有不同种类的点,它们都继承自 MyPoint 类。对于某些点,它只是将它们按原样打印在屏幕上,其他点可以忽略,其他点可以添加,因此与它们相关的某种逻辑可能会变得复杂。

如何实际绘制图形不是这里的主要问题。困扰我的是如何使这个GraphicMaker类不会成为所谓的God-Object的代码逻辑。

制作这样的东西很容易:

你会怎么做这样的事情?我有一种感觉,正确的方法是将绘图逻辑放在每个 Point 对象上(因此 Point 的每个子类都知道如何绘制自己),但出现了两个问题:

  1. 有些点需要知道 GraphicObject 类中存在的所有其他点才能知道如何绘制自己。
  2. 我可以将 Graphic 类中的许多方法/属性公开,这样所有点都可以引用 Graphic 类,并且可以根据需要制作所有逻辑,但这不是要付出很大的代价吗?想上神班?
0 投票
5 回答
1216 浏览

c# - MVVM 和避免 Monolithic God 对象

我正处于一个大型项目的完成阶段,该项目有几个大型组件:图像采集、图像处理、数据存储、工厂 I/O(自动化项目)和其他几个。

这些组件中的每一个都是相当独立的,但是要使项目作为一个整体运行,我至少需要每个组件的一个实例。每个组件还有一个 ViewModel 和 View (WPF) 用于监控状态和改变事物。

我的问题是实例化所有这些对象的最安全、最有效和最可维护的方法,将一个类订阅到另一个类中的事件,并为所有这些拥有一个通用的 ViewModel 和 View。

如果我有一个名为 God 的类,它拥有所有这些对象的私有实例,那会更好吗?我过去曾这样做过,并为此感到后悔。

或者如果上帝依靠这些对象的单例实例来让球滚动起来会更好吗?

或者,应该 Program.cs(或 Main(...) 所在的任何地方)实例化所有这些组件,并将它们作为参数传递给上帝,然后让他(窃笑)和他的 ViewModel 处理运行这个项目的细节。

我很想听听任何其他建议。

谢谢!

0 投票
4 回答
2663 浏览

java - 我如何编写控制器而不使其成为上帝对象?

在我的应用程序中,我有一个Controller由 main 方法启动的。控制器初始化钩子、数据库连接、UI、另一个连接和其他东西。它拥有程序的大部分状态(不,它不是单例)。在另一个示例中,机器人的控制器处理解释和发送命令。两者都是相当大的文件。

我已经阅读了有关上帝对象的内容,但我真的不知道如何将其拆分。如果我在 bot 中拆分解释器和调度器,它将产生一个可怕的调用链(类似于getBot().getParser().getOutput().sendMessage(recipient, message))。同样,在第一个控制器中,如果我将它们分开,您将只有包含字段和一些别名实用程序方法的 Data 对象。把它们分开只会让事情变得更糟。在你认为它不可维护之前,它实际上不是。我什至没有编写 Bot 控制器,但我仍然知道发生了什么。

但问题是 Bot 类有 2000 行长(如果我去掉 Javadoc 注释,可能会更短),而 Bot 大约有 1000 行长。很多行=上帝的对象。但是一个项目的一两个核心类可以吗?

0 投票
5 回答
282 浏览

php - 我有一个包含 14 个静态方法和 4 个静态属性的类 - 这很糟糕吗?

我一直在编写一个恰好 450 行长的 PHP 类,它包含 14 个静态方法和 4 个静态属性以及 6 个常量(以及私有__construct()__clone())。

我想知道这是我做错了什么,我的班级是邪恶的吗?

当你使用这个类时,你总是调用一个方法,比如:

然后你完全不理会它,所以觉得让它可构造是愚蠢的?

用它来构造对象真的没有多大意义,因为它更像是一个包含一些你可以直接调用的方法的工具。

实际上,在这 14 个方法中,有 7 个是公共的——其余的都是私有的,供类使用。

0 投票
4 回答
3444 浏览

oop - 管理多个类的类是“神对象”吗?

阅读关于上帝对象的维基百科条目,它说当一个类知道太多或做得太多时,它就是一个上帝对象。

我看到了这背后的逻辑,但如果这是真的,那么你如何将每个不同的类结合起来?你不总是使用大师班来连接窗口管理、数据库连接等吗?