如果您使用Inversion of Control,构造函数的大小是否重要?

时间:2021-11-07 21:28:59

So I've got maybe 10 objects each of which has 1-3 dependencies (which I think is ok as far as loose coupling is concerned) but also some settings that can be used to define behavior (timeout, window size, etc).

所以我有10个对象,每个对象有1-3个依赖项(我认为就松散耦合而言是可行的),还有一些可用于定义行为的设置(超时,窗口大小等)。

Now before I started using an Inversion of Control container I would have created a factory and maybe even a simple ObjectSettings object for each of the objects that requires more than 1 setting to keep the size of the constructor to the recommended "less than 4" parameter size. I am now using an inversion of control container and I just don't see all that much of a point to it. Sure I might get a constructor with 7 parameters, but who cares? It's all being filled out by the IoC anyways.

在我开始使用Inversion of Control容器之前,我会创建一个工厂,甚至可能为每个需要多于1个设置的对象创建一个简单的ObjectSettings对象,以将构造函数的大小保持为建议的“小于4”参数尺寸。我现在正在使用控制容器的反转,我只是没有看到它的重点。当然,我可能会得到一个带有7个参数的构造函数,但谁在乎呢?无论如何,这一切都被IoC填补了。

Am I missing something here or is this basically correct?

我在这里遗漏了什么或这基本上是正确的吗?

5 个解决方案

#1


6  

The relationship between class complexity and the size of the IoC constructor had not occurred to me before reading this question, but my analysis below suggests that having many arguments in the IoC constructor is a code smell to be aware of when using IoC. Having a goal to stick to a short constructor argument list will help you keep the classes themselves simple. Following the single responsibility principle will guide you towards this goal.

在阅读这个问题之前,我没有想到类复杂性和IoC构造函数的大小之间的关系,但我的分析表明,在IoC构造函数中有许多参数是使用IoC时要注意的代码味道。有一个目标是坚持一个简短的构造函数参数列表将帮助您保持类本身简单。遵循单一责任原则将指导您实现这一目标。

I work on a system that currently has 122 classes that are instantiated using the Spring.NET framework. All relationships between these classes are set up in their constructors. Admittedly, the system has its fair share of less than perfect code where I have broken a few rules. (But, hey, our failures are opportunities to learn!)

我在一个系统上工作,该系统目前有122个使用Spring.NET框架实例化的类。这些类之间的所有关系都在它们的构造函数中设置。不可否认,该系统有一些不完美的代码,我已经打破了一些规则。 (但是,嘿,我们的失败是学习的机会!)

The constructors of those classes have varying numbers of arguments, which I show in the table below.

这些类的构造函数具有不同数量的参数,我在下表中显示。

Number of constructor arguments    Number of classes
           0                             57
           1                             19
           2                             25
           3                              9
           4                              3
           5                              1
           6                              3
           7                              2
           8                              2

The classes with zero arguments are either concrete strategy classes, or classes that respond to events by sending data to external systems.

具有零参数的类是具体的策略类,或者是通过将数据发送到外部系统来响应事件的类。

Those with 5 or 6 arguments are all somewhat inelegant and could use some refactoring to simplify them.

那些有5或6个参数的人都有点不优雅,可以使用一些重构来简化它们。

The four classes with 7 or 8 arguments are excellent examples of God objects. They ought to be broken up, and each is already on my list of trouble-spots within the system.

具有7或8个参数的四个类是上帝对象的极好例子。它们应该被分解,并且每个都已经在我的系统中的故障点列表中。

The remaining classes (1 to 4 arguments) are (mostly) simply designed, easy to understand, and conform to the single responsibility principle.

其余的类(1到4个参数)(大多数)设计简单,易于理解,并符合单一责任原则。

#2


2  

The need for many dependencies (maybe over 8) could be indicative of a design flaw but in general I think there is no problem as long as the design is cohesive.

对许多依赖项(可能超过8个)的需求可能表明存在设计缺陷,但总的来说,只要设计具有凝聚力,我认为没有问题。

Also, consider using a service locator or static gateway for infrastructure concerns such as logging and authorization rather than cluttering up the constructor arguments.

此外,考虑使用服务定位器或静态网关来解决基础结构问题,例如日志记录和授权,而不是使构造函数参数混乱。

EDIT: 8 probably is too many but I figured there'd be the odd case for it. After looking at Lee's post I agree, 1-4 is usually good.

编辑:8可能是太多但我认为它有奇怪的情况。看了李的帖子我同意,1-4通常是好的。

#3


1  

G'day George,

First off, what are the dependencies between the objects?

首先,对象之间的依赖关系是什么?

Lots of "isa" relationships? Lots of "hasa" relationships?

很多“isa”关系?很多“哈萨”的关系?

Lots of fan-in? Or fan-out?

很多粉丝?或扇出?

George's response: "has-a mostly, been trying to follow the composition over inheritance advice...why would it matter though?"

乔治的回答是:“大多数人都试图遵循继承建议的构成......但为什么会这么重要呢?”

As it's mostly "hasa" you should be all right.

因为它主要是“哈萨”你应该没事。

Better make sure that your construction (and destruction) of the components is done correctly though to prevent memory leaks.

更好地确保组件的构造(和销毁)正确完成,以防止内存泄漏。

And, if this is in C++, make sure you use virtual destructors?

而且,如果这是在C ++中,请确保使用虚拟析构函数?

#4


1  

This is a tough one, and why I favor a hybrid approach where appropriate properties are mutable and only immutable properties and required dependencies without a useful default are part of the constructor. Some classes are constructed with the essentials, then tuned if necessary via setters.

这是一个艰难的问题,为什么我喜欢混合方法,其中适当的属性是可变的,只有不可变的属性和没有有用默认值的必需依赖项是构造函数的一部分。有些类是使用必需品构建的,然后在必要时通过setter进行调整。

#5


0  

It all depends upon what kind of container that you have used to do the IOC and what approaches the container takes whether it uses annotations or configuration file to saturate the object to be instiantiated. Furthermore, if your constructor parameters are just plain primitive data types then it is not really a big deal; however if you have non-primitive types then in my opinion, you can use the Property based DI rather than consutructor based DI.

这一切都取决于您用来做IOC的容器类型以及容器采用什么方法,无论它是使用注释还是配置文件来使对象充满信息。此外,如果你的构造函数参数只是简单的原始数据类型,那么它并不是一个大问题;但是如果您有非原始类型,那么在我看来,您可以使用基于属性的DI而不是基于构造函数的DI。

#1


6  

The relationship between class complexity and the size of the IoC constructor had not occurred to me before reading this question, but my analysis below suggests that having many arguments in the IoC constructor is a code smell to be aware of when using IoC. Having a goal to stick to a short constructor argument list will help you keep the classes themselves simple. Following the single responsibility principle will guide you towards this goal.

在阅读这个问题之前,我没有想到类复杂性和IoC构造函数的大小之间的关系,但我的分析表明,在IoC构造函数中有许多参数是使用IoC时要注意的代码味道。有一个目标是坚持一个简短的构造函数参数列表将帮助您保持类本身简单。遵循单一责任原则将指导您实现这一目标。

I work on a system that currently has 122 classes that are instantiated using the Spring.NET framework. All relationships between these classes are set up in their constructors. Admittedly, the system has its fair share of less than perfect code where I have broken a few rules. (But, hey, our failures are opportunities to learn!)

我在一个系统上工作,该系统目前有122个使用Spring.NET框架实例化的类。这些类之间的所有关系都在它们的构造函数中设置。不可否认,该系统有一些不完美的代码,我已经打破了一些规则。 (但是,嘿,我们的失败是学习的机会!)

The constructors of those classes have varying numbers of arguments, which I show in the table below.

这些类的构造函数具有不同数量的参数,我在下表中显示。

Number of constructor arguments    Number of classes
           0                             57
           1                             19
           2                             25
           3                              9
           4                              3
           5                              1
           6                              3
           7                              2
           8                              2

The classes with zero arguments are either concrete strategy classes, or classes that respond to events by sending data to external systems.

具有零参数的类是具体的策略类,或者是通过将数据发送到外部系统来响应事件的类。

Those with 5 or 6 arguments are all somewhat inelegant and could use some refactoring to simplify them.

那些有5或6个参数的人都有点不优雅,可以使用一些重构来简化它们。

The four classes with 7 or 8 arguments are excellent examples of God objects. They ought to be broken up, and each is already on my list of trouble-spots within the system.

具有7或8个参数的四个类是上帝对象的极好例子。它们应该被分解,并且每个都已经在我的系统中的故障点列表中。

The remaining classes (1 to 4 arguments) are (mostly) simply designed, easy to understand, and conform to the single responsibility principle.

其余的类(1到4个参数)(大多数)设计简单,易于理解,并符合单一责任原则。

#2


2  

The need for many dependencies (maybe over 8) could be indicative of a design flaw but in general I think there is no problem as long as the design is cohesive.

对许多依赖项(可能超过8个)的需求可能表明存在设计缺陷,但总的来说,只要设计具有凝聚力,我认为没有问题。

Also, consider using a service locator or static gateway for infrastructure concerns such as logging and authorization rather than cluttering up the constructor arguments.

此外,考虑使用服务定位器或静态网关来解决基础结构问题,例如日志记录和授权,而不是使构造函数参数混乱。

EDIT: 8 probably is too many but I figured there'd be the odd case for it. After looking at Lee's post I agree, 1-4 is usually good.

编辑:8可能是太多但我认为它有奇怪的情况。看了李的帖子我同意,1-4通常是好的。

#3


1  

G'day George,

First off, what are the dependencies between the objects?

首先,对象之间的依赖关系是什么?

Lots of "isa" relationships? Lots of "hasa" relationships?

很多“isa”关系?很多“哈萨”的关系?

Lots of fan-in? Or fan-out?

很多粉丝?或扇出?

George's response: "has-a mostly, been trying to follow the composition over inheritance advice...why would it matter though?"

乔治的回答是:“大多数人都试图遵循继承建议的构成......但为什么会这么重要呢?”

As it's mostly "hasa" you should be all right.

因为它主要是“哈萨”你应该没事。

Better make sure that your construction (and destruction) of the components is done correctly though to prevent memory leaks.

更好地确保组件的构造(和销毁)正确完成,以防止内存泄漏。

And, if this is in C++, make sure you use virtual destructors?

而且,如果这是在C ++中,请确保使用虚拟析构函数?

#4


1  

This is a tough one, and why I favor a hybrid approach where appropriate properties are mutable and only immutable properties and required dependencies without a useful default are part of the constructor. Some classes are constructed with the essentials, then tuned if necessary via setters.

这是一个艰难的问题,为什么我喜欢混合方法,其中适当的属性是可变的,只有不可变的属性和没有有用默认值的必需依赖项是构造函数的一部分。有些类是使用必需品构建的,然后在必要时通过setter进行调整。

#5


0  

It all depends upon what kind of container that you have used to do the IOC and what approaches the container takes whether it uses annotations or configuration file to saturate the object to be instiantiated. Furthermore, if your constructor parameters are just plain primitive data types then it is not really a big deal; however if you have non-primitive types then in my opinion, you can use the Property based DI rather than consutructor based DI.

这一切都取决于您用来做IOC的容器类型以及容器采用什么方法,无论它是使用注释还是配置文件来使对象充满信息。此外,如果你的构造函数参数只是简单的原始数据类型,那么它并不是一个大问题;但是如果您有非原始类型,那么在我看来,您可以使用基于属性的DI而不是基于构造函数的DI。