一个班级应该有多少个构造函数?

时间:2022-11-15 00:14:09

I'm currently modifying a class that has 9 different constructors. Now overall I believe this class is very poorly designed... so I'm wondering if it is poor design for a class to have so many constructors.

我目前正在修改一个有9种不同构造函数的类。现在整体而言,我认为这个类的设计非常糟糕...所以我想知道如果一个类有这么多构造函数的设计是不好的。

A problem has arisen because I recently added two constructors to this class in an attempt to refactor and redesign a class (SomeManager in the code below) so that it is unit testable and doesn't rely on every one of its methods being static. However, because the other constructors were conveniently hidden out of view about a hundred lines below the start of the class I didn't spot them when I added my constructors.

出现了一个问题,因为我最近在这个类中添加了两个构造函数,试图重构和重新设计一个类(下面代码中的SomeManager),这样它就是单元可测试的,并且不依赖于它的每个方法都是静态的。但是,因为其他构造函数被方便地隐藏在类的开头下方大约一百行之外,所以当我添加构造函数时,我没有发现它们。

What is happening now is that code that calls these other constructors depends on the SomeManager class to already be instantiated because it used to be static....the result is a null reference exception.

现在发生的事情是调用这些其他构造函数的代码依赖于已经实例化的SomeManager类,因为它曾经是静态的......结果是一个空引用异常。

So my question is how do I fix this issue? By trying to reduce the number of constructors? By making all the existing constructors take an ISomeManager parameter?

所以我的问题是如何解决这个问题?通过尝试减少构造函数的数量?通过使所有现有构造函数采用ISomeManager参数?

Surely a class doesn't need 9 constructors! ...oh and to top it off there are 6000 lines of code in this file!

当然一个班级不需要9个构造函数! ...哦,最重要的是这个文件中有6000行代码!

Here's a censored representation of the constructors I'm talking about above:

这是我正在讨论的构造函数的审查表示:

public MyManager()
    : this(new SomeManager()){} //this one I added

public MyManager(ISomeManager someManager) //this one I added
{
    this.someManager = someManager;
}

public MyManager(int id)
    : this(GetSomeClass(id)) {}

public MyManager(SomeClass someClass)
    : this(someClass, DateTime.Now){}

public MyManager(SomeClass someClass, DateTime someDate)
{
    if (someClass != null)
       myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(SomeOtherClass someOtherClass)
    : this(someOtherClass, DateTime.Now){}

public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
    myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(YetAnotherClass yetAnotherClass)
    : this(yetAnotherClass, DateTime.Now){}

public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
    myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}

Update:

Thanks everyone for your responses...they have been excellent!

感谢大家的回复......他们一直很棒!

Just thought I'd give an update on what I've ended up doing.

只是想我会更新我最终做的事情。

In order to address the null reference exception issue I've modified the additional constructors to take an ISomeManager.

为了解决空引用异常问题,我修改了其他构造函数以获取ISomeManager。

At the moment my hands are tied when it comes to being allowed to refactor this particular class so I'll be flagging it as one on my todo list of classes to redesign when I have some spare time. At the moment I'm just glad I've been able to refactor the SomeManager class...it was just as huge and horrible as this MyManager class.

目前,当我被允许重构这个特定课程时,我的双手被束缚,所以当我有空余时间时,我会将其标记为我的待办事项列表中的一个重新设计。目前我很高兴我能够重构SomeManager类......它和MyManager类一样巨大而且可怕。

When I get around to redesigning MyManager I'll be looking for a way to extract the functionality into two or three different classes...or however many it takes to ensure SRP is followed.

当我开始重新设计MyManager时,我将寻找一种方法将功能提取到两个或三个不同的类......或者确保遵循SRP所需的许多方法。

Ultimately, I haven't come to the conclusion that there is a maximum number of constructors for any given class but I believe that in this particular instance I can create two or three classes each with two or three constructors each..

最后,我还没有得出结论,任何给定类都有最大数量的构造函数,但我相信在这个特定的实例中,我可以创建两个或三个类,每个类有两个或三个构造函数。

15 个解决方案

#1


A class should do one thing and one thing only. If it has so many constructors it seems to be a tell tale sign that it's doing too many things.

一堂课应该只做一件事,一件事。如果它有这么多的构造函数,它似乎是一个告诉故事标志,它做了太多的事情。

Using multiple constructors to force the correct creation of instances of the object in a variety of circumstances but 9 seems like a lot. I would suspect there is an interface in there and a couple of implementations of the interface that could be dragged out. Each of those would likely have from one to a few constructors each relevant to their specialism.

使用多个构造函数来强制在各种情况下正确创建对象的实例,但9似乎很多。我怀疑那里有一个接口,可以拖出一些接口的实现。每个人都可能有一个到几个与他们的专业相关的建设者。

#2


As little as possible,
As many as necessary.

尽可能少,尽可能多。

#3


9 constructors and 6000 lines in class is a sign of code smell. You should re-factor that class. If the class is having lot of responsibilities and then you should separate them out. If the responsibilities are similar but little deviation then you should look to implement inheritance buy creating a interface and different implementations.

9个构造函数和6000行代码是代码气味的标志。你应该重新考虑那个班级。如果班级有很多责任,那么你应该将它们分开。如果责任相似但偏差很小,那么你应该寻求实现继承购买创建一个接口和不同的实现。

#4


If you arbitrarily limit the number of constructors in a class, you could end up with a constructor that has a massive number of arguments. I would take a class with 100 constructors over a constructor with 100 arguments everyday. When you have a lot of constructors, you can choose to ignore most of them, but you can't ignore method arguments.

如果你任意限制一个类中的构造函数的数量,你最终可能会得到一个具有大量参数的构造函数。我会在每天有100个参数的构造函数上使用100个构造函数的类。当你有很多构造函数时,你可以选择忽略它们中的大多数,但你不能忽略方法参数。

Think of the set of constructors in a class as a mathematical function mapping M sets (where each set is a single constructor's argument list) to N instances of the given class. Now say, class Bar can take a Foo in one of its constructors, and class Foo takes a Baz as a constructor argument as we show here:

将类中的构造函数集视为将M个集合(其中每个集合是单个构造函数的参数列表)映射到给定类的N个实例的数学函数。现在说,类Bar可以在其构造函数中使用Foo,类Foo将Baz作为构造函数参数,如下所示:

    Foo --> Bar
    Baz --> Foo

We have the option of adding another constructor to Bar such that:

我们可以选择向Bar添加另一个构造函数,以便:

    Foo --> Bar
    Baz --> Bar
    Baz --> Foo

This can be convenient for users of the Bar class, but since we already have a path from Baz to Bar (through Foo), we don't need that additional constructor. Hence, this is where the judgement call resides.

这对Bar类的用户来说很方便,但是因为我们已经有了从Baz到Bar(通过Foo)的路径,所以我们不需要那个额外的构造函数。因此,这是判决呼叫所在的位置。

But if we suddenly add a new class called Qux and we find ourselves in need to create an instance of Bar from it: we have to add a constructor somewhere. So it could either be:

但是如果我们突然添加一个名为Qux的新类,我们发现自己需要从中创建一个Bar实例:我们必须在某处添加一个构造函数。所以它可能是:

    Foo --> Bar
    Baz --> Bar
    Qux --> Bar
    Baz --> Foo

OR:

    Foo --> Bar
    Baz --> Bar
    Baz --> Foo
    Qux --> Foo

The later would have a more even distribution of constructors between the classes but whether it is a better solution depends largely on the way in which they are going to be used.

后者在类之间会有更均匀的构造函数分布,但它是否是更好的解决方案在很大程度上取决于它们的使用方式。

#5


The answer: 1 (with regards to injectables).

答案:1(关于注射剂)。

Here's a brilliant article on the topic: Dependency Injection anti-pattern: multiple constructors

这是一篇关于该主题的精彩文章:依赖注入反模式:多个构造函数

Summarized, your class's constructor should be for injecting dependencies and your class should be open about its dependencies. A dependency is something your class needs. Not something it wants, or something it would like, but can do without. It's something it needs.

总而言之,您的类的构造函数应该用于注入依赖项,并且您的类应该公开其依赖项。依赖是您的课程所需要的。不是它想要的东西,或者它想要的东西,但是可以不用。这是它需要的东西。

So having optional constructor parameters, or overloaded constructors, makes no sense to me. Your sole public constructor should define your class's set of dependencies. It's the contract your class is offering, that says "If you give me an IDigitalCamera, an ISomethingWorthPhotographing and an IBananaForScale, I'll give you the best damn IPhotographWithScale you can imagine. But if you skimp on any of those things, you're on your own".

因此,拥有可选的构造函数参数或重载的构造函数对我来说毫无意义。您唯一的公共构造函数应该定义您的类的依赖项集。这是你的班级提供的合同,上面写着“如果你给我一个IDigitalCamera,一个ISomethingWorthPhotographing和一个IBananaForScale,我会给你最好的,你可以想象的IPhotographWithScale。但如果你吝啬任何这些东西,你就是在你自己“。

Here's an article, by Mark Seemann, that goes into some of the finer reasons for having a canonical constructor: State Your Dependency Intent

这是马克·西曼(Mark Seemann)撰写的一篇文章,该文章介绍了拥有规范构造函数的一些更好的理由:陈述你的依赖性意图

#6


It's not just this class you have to worry about re-factoring. It's all the other classes as well. And this is probably just one thread in the tangled skein that is your code base. You have my sympathy... I'm in the same boat. Boss wants everything unit tested, doesn't want to rewrite code so we can unit test. End up doing some ugly hacks to make it work. You're going to have to re-write everything that is using the static class to no longer use it, and probably pass it around a lot more... or you can wrap it in a static proxy that accessses a singleton. That way you an at least mock the singleton out, and test that way.

不仅仅是这门课你还要担心重新分解。这也是所有其他课程。这可能只是纠结的绞纱中的一个线程,也就是你的代码库。你有我的同情......我在同一条船上。老板想要所有单元测试,不想重写代码,所以我们可以进行单元测试。最后做一些丑陋的黑客让它工作。您将不得不重新编写使用静态类的所有内容以便不再使用它,并且可能会将其传递给更多...或者您可以将其包装在访问单例的静态代理中。这样你至少可以嘲笑单身人士,并以这种方式进行测试。

#7


Your problem isn't the number of constructors. Having 9 constructors is more than usual, but I don't think it is necessarily wrong. It's certainly not the source of your problem. The real problem is that the initial design was all static methods. This is really a special case of the classes being too tightly coupled. The now-failing classes are bound to the idea that the functions are static. There isn't much you can do about that from the class in question. If you want to make this class non-static, you'll have to undo all that coupling that was written into the code by others. Modify the class to be non-static and then update all of the callers to instantiate a class first (or get one from a singleton). One way to find all of the callers is to make the functions private and let the compiler tell you.

你的问题不是构造函数的数量。有9个构造函数比平常更多,但我认为它不一定是错误的。它肯定不是你问题的根源。真正的问题是初始设计都是静态方法。这实际上是类太紧密耦合的特殊情况。现在失败的类必然会认为函数是静态的。关于这个课程,你无能为力。如果要使此类非静态,则必须撤消其他人写入代码的所有耦合。将类修改为非静态,然后更新所有调用者以首先实例化一个类(或从单例中获取一个)。找到所有调用者的一种方法是将函数设为私有,让编译器告诉您。

At 6000 lines, the class is not very cohesive. It's probably trying to do too much. In a perfect world you would refactor the class (and those calling it) into several smaller classes.

在6000行,课程不是很有凝聚力。它可能试图做太多。在一个完美的世界中,你会将类(以及那些调用它)重构为几个较小的类。

#8


Enough to do its task, but remember the Single Responsibility Principle, which states that a class should only have a single responsibility. With that in mind there are probably very few cases where it makes sense to have 9 constructors.

足以完成其任务,但要记住单一责任原则,该原则规定一个班级应该只承担一项责任。考虑到这一点,可能很少有9个构造函数有意义的情况。

#9


I limit my class to only have one real constructor. I define the real constructor as the one that has a body. I then have other constructors that just delegate to the real one depending on their parameters. Basically, I'm chaining my constructors.

我限制我的类只有一个真正的构造函数。我将真正的构造函数定义为具有正文的构造函数。然后我有其他构造函数,根据它们的参数委托给真正的构造函数。基本上,我正在链接我的构造函数。

Looking at your class, there are four constructors that has a body:

看看你的班级,有四个构造函数有一个正文:

public MyManager(ISomeManager someManager) //this one I added
{
    this.someManager = someManager;
}

public MyManager(SomeClass someClass, DateTime someDate)
{
    if (someClass != null)
       myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
    myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
    myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}

The first one is the one that you've added. The second one is similar to the last two but there is a conditional. The last two constructors are very similar, except for the type of parameter.

第一个是你添加的那个。第二个类似于最后两个,但有一个条件。除参数类型外,最后两个构造函数非常相似。

I would try to find a way to create just one real constructor, making either the 3rd constructor delegate to the 4th or the other way around. I'm not really sure if the first constructor can even fit in as it is doing something quite different than the old constructors.

我会尝试找到一种方法来创建一个真正的构造函数,使第三个构造函数委托给第四个或另一个方法。我不确定第一个构造函数是否可以适应,因为它正在做一些与旧构造函数完全不同的东西。

If you are interested in this approach, try to find a copy of the Refactoring to Patterns book and then go to the Chain Constructors page.

如果您对此方法感兴趣,请尝试查找Refactoring to Patterns一书的副本,然后转到Chain Constructors页面。

#10


Surely a class should have as many constructors as are required by the class... this doesnt mean than bad design can take over.

当然,一个班级应该有尽可能多的班级所需的构造函数......这并不意味着糟糕的设计可以接管。

Class design should be that a constructor creates a valid object after is has finished. If you can do that with 1 param or 10 params then so be it!

类设计应该是构造函数在完成后创建有效对象。如果你能用1个参数或10个参数做到这一点那么就这样吧!

#11


It seems to me that this class is used to do way, way to much. I think you really should refactor the class and split it into several more specialized classes. Then you can get rid of all these constructors and have a cleaner, more flexible, more maintainable and more readable code.

在我看来,这门课程已经习惯了。我认为你真的应该重构这个类并将它分成几个更专业的类。然后,您可以摆脱所有这些构造函数,并拥有更清晰,更灵活,更易于维护和更易读的代码。

This was not at direct answer to your question, but i do believe that if it is necessary for a class to have more than 3-4 constructors its a sign that it probably should be refactored into several classes.

这不是你问题的直接答案,但我确实认为,如果一个类有超过3-4个构造函数的必要性,那么它可能应该被重构为几个类。

Regards.

#12


The only "legit" case I can see from you code is if half of them are using an obsolete type that you are working to remove from the code. When I work like this I frequently have double sets of constructors, where half of them are marked @Deprecated or @Obsolete. But your code seems to be way beyond that stage....

我可以从您的代码中看到的唯一“合法”案例是,其中一半是使用您正在努力从代码中删除的过时类型。当我像这样工作时,我经常有两组构造函数,其中一半标记为@Deprecated或@Obsolete。但是你的代码似乎超出了那个阶段....

#13


I generally have one, which may have some default parameters. The constructor will only do the minimum setup of the object so it's valid by the time it's been created. If I need more, I'll create static factory methods. Kind of like this:

我通常有一个,可能有一些默认参数。构造函数只会对对象进行最小化设置,因此它在创建时有效。如果我需要更多,我将创建静态工厂方法。有点像这样:

class Example {
public:
  static FromName(String newname) { 
    Example* result = new Example();
    result.name_ = newname;
    return result;
  }
  static NewStarter() { return new Example(); }

private:
  Example();
}

Okay that's not actually a very good example, I'll see if I can think of a better one and edit it in.

好吧,这实际上并不是一个很好的例子,我会看看我是否能想到更好的一个并编辑它。

#14


The awnser is: NONE

awnser是:NONE

Look at the Language Dylan. Its has a other System.

看看语言迪伦。它有另一个系统。

Instat of a constructors you add more values to your slots (members) then in other language. You can add a "init-keyword". Then if you make a instance you can set the slot to the value you want.

构造函数的Instat可以为插槽(成员)添加更多值,然后使用其他语言。您可以添加“init-keyword”。然后,如果您创建实例,则可以将插槽设置​​为所需的值。

Ofcourse you can set 'required-init-keyword:' and there are more options you can use.

当然你可以设置'required-init-keyword:',​​你可以使用更多的选项。

It works and it is easy. I dont miss the old system. Writing constructors (and destructors).

它很有效,很容易。我不会错过旧系统。编写构造函数(和析构函数)。

(btw. its still a very fast language)

(顺便说一下,它仍然是一种非常快速的语言)


#15


I think that a class that has more than one constructor has more than one responsibility. Would be nice to be convinced about the opposite however.

我认为具有多个构造函数的类具有多个责任。不过很高兴相信相反的情况。

#1


A class should do one thing and one thing only. If it has so many constructors it seems to be a tell tale sign that it's doing too many things.

一堂课应该只做一件事,一件事。如果它有这么多的构造函数,它似乎是一个告诉故事标志,它做了太多的事情。

Using multiple constructors to force the correct creation of instances of the object in a variety of circumstances but 9 seems like a lot. I would suspect there is an interface in there and a couple of implementations of the interface that could be dragged out. Each of those would likely have from one to a few constructors each relevant to their specialism.

使用多个构造函数来强制在各种情况下正确创建对象的实例,但9似乎很多。我怀疑那里有一个接口,可以拖出一些接口的实现。每个人都可能有一个到几个与他们的专业相关的建设者。

#2


As little as possible,
As many as necessary.

尽可能少,尽可能多。

#3


9 constructors and 6000 lines in class is a sign of code smell. You should re-factor that class. If the class is having lot of responsibilities and then you should separate them out. If the responsibilities are similar but little deviation then you should look to implement inheritance buy creating a interface and different implementations.

9个构造函数和6000行代码是代码气味的标志。你应该重新考虑那个班级。如果班级有很多责任,那么你应该将它们分开。如果责任相似但偏差很小,那么你应该寻求实现继承购买创建一个接口和不同的实现。

#4


If you arbitrarily limit the number of constructors in a class, you could end up with a constructor that has a massive number of arguments. I would take a class with 100 constructors over a constructor with 100 arguments everyday. When you have a lot of constructors, you can choose to ignore most of them, but you can't ignore method arguments.

如果你任意限制一个类中的构造函数的数量,你最终可能会得到一个具有大量参数的构造函数。我会在每天有100个参数的构造函数上使用100个构造函数的类。当你有很多构造函数时,你可以选择忽略它们中的大多数,但你不能忽略方法参数。

Think of the set of constructors in a class as a mathematical function mapping M sets (where each set is a single constructor's argument list) to N instances of the given class. Now say, class Bar can take a Foo in one of its constructors, and class Foo takes a Baz as a constructor argument as we show here:

将类中的构造函数集视为将M个集合(其中每个集合是单个构造函数的参数列表)映射到给定类的N个实例的数学函数。现在说,类Bar可以在其构造函数中使用Foo,类Foo将Baz作为构造函数参数,如下所示:

    Foo --> Bar
    Baz --> Foo

We have the option of adding another constructor to Bar such that:

我们可以选择向Bar添加另一个构造函数,以便:

    Foo --> Bar
    Baz --> Bar
    Baz --> Foo

This can be convenient for users of the Bar class, but since we already have a path from Baz to Bar (through Foo), we don't need that additional constructor. Hence, this is where the judgement call resides.

这对Bar类的用户来说很方便,但是因为我们已经有了从Baz到Bar(通过Foo)的路径,所以我们不需要那个额外的构造函数。因此,这是判决呼叫所在的位置。

But if we suddenly add a new class called Qux and we find ourselves in need to create an instance of Bar from it: we have to add a constructor somewhere. So it could either be:

但是如果我们突然添加一个名为Qux的新类,我们发现自己需要从中创建一个Bar实例:我们必须在某处添加一个构造函数。所以它可能是:

    Foo --> Bar
    Baz --> Bar
    Qux --> Bar
    Baz --> Foo

OR:

    Foo --> Bar
    Baz --> Bar
    Baz --> Foo
    Qux --> Foo

The later would have a more even distribution of constructors between the classes but whether it is a better solution depends largely on the way in which they are going to be used.

后者在类之间会有更均匀的构造函数分布,但它是否是更好的解决方案在很大程度上取决于它们的使用方式。

#5


The answer: 1 (with regards to injectables).

答案:1(关于注射剂)。

Here's a brilliant article on the topic: Dependency Injection anti-pattern: multiple constructors

这是一篇关于该主题的精彩文章:依赖注入反模式:多个构造函数

Summarized, your class's constructor should be for injecting dependencies and your class should be open about its dependencies. A dependency is something your class needs. Not something it wants, or something it would like, but can do without. It's something it needs.

总而言之,您的类的构造函数应该用于注入依赖项,并且您的类应该公开其依赖项。依赖是您的课程所需要的。不是它想要的东西,或者它想要的东西,但是可以不用。这是它需要的东西。

So having optional constructor parameters, or overloaded constructors, makes no sense to me. Your sole public constructor should define your class's set of dependencies. It's the contract your class is offering, that says "If you give me an IDigitalCamera, an ISomethingWorthPhotographing and an IBananaForScale, I'll give you the best damn IPhotographWithScale you can imagine. But if you skimp on any of those things, you're on your own".

因此,拥有可选的构造函数参数或重载的构造函数对我来说毫无意义。您唯一的公共构造函数应该定义您的类的依赖项集。这是你的班级提供的合同,上面写着“如果你给我一个IDigitalCamera,一个ISomethingWorthPhotographing和一个IBananaForScale,我会给你最好的,你可以想象的IPhotographWithScale。但如果你吝啬任何这些东西,你就是在你自己“。

Here's an article, by Mark Seemann, that goes into some of the finer reasons for having a canonical constructor: State Your Dependency Intent

这是马克·西曼(Mark Seemann)撰写的一篇文章,该文章介绍了拥有规范构造函数的一些更好的理由:陈述你的依赖性意图

#6


It's not just this class you have to worry about re-factoring. It's all the other classes as well. And this is probably just one thread in the tangled skein that is your code base. You have my sympathy... I'm in the same boat. Boss wants everything unit tested, doesn't want to rewrite code so we can unit test. End up doing some ugly hacks to make it work. You're going to have to re-write everything that is using the static class to no longer use it, and probably pass it around a lot more... or you can wrap it in a static proxy that accessses a singleton. That way you an at least mock the singleton out, and test that way.

不仅仅是这门课你还要担心重新分解。这也是所有其他课程。这可能只是纠结的绞纱中的一个线程,也就是你的代码库。你有我的同情......我在同一条船上。老板想要所有单元测试,不想重写代码,所以我们可以进行单元测试。最后做一些丑陋的黑客让它工作。您将不得不重新编写使用静态类的所有内容以便不再使用它,并且可能会将其传递给更多...或者您可以将其包装在访问单例的静态代理中。这样你至少可以嘲笑单身人士,并以这种方式进行测试。

#7


Your problem isn't the number of constructors. Having 9 constructors is more than usual, but I don't think it is necessarily wrong. It's certainly not the source of your problem. The real problem is that the initial design was all static methods. This is really a special case of the classes being too tightly coupled. The now-failing classes are bound to the idea that the functions are static. There isn't much you can do about that from the class in question. If you want to make this class non-static, you'll have to undo all that coupling that was written into the code by others. Modify the class to be non-static and then update all of the callers to instantiate a class first (or get one from a singleton). One way to find all of the callers is to make the functions private and let the compiler tell you.

你的问题不是构造函数的数量。有9个构造函数比平常更多,但我认为它不一定是错误的。它肯定不是你问题的根源。真正的问题是初始设计都是静态方法。这实际上是类太紧密耦合的特殊情况。现在失败的类必然会认为函数是静态的。关于这个课程,你无能为力。如果要使此类非静态,则必须撤消其他人写入代码的所有耦合。将类修改为非静态,然后更新所有调用者以首先实例化一个类(或从单例中获取一个)。找到所有调用者的一种方法是将函数设为私有,让编译器告诉您。

At 6000 lines, the class is not very cohesive. It's probably trying to do too much. In a perfect world you would refactor the class (and those calling it) into several smaller classes.

在6000行,课程不是很有凝聚力。它可能试图做太多。在一个完美的世界中,你会将类(以及那些调用它)重构为几个较小的类。

#8


Enough to do its task, but remember the Single Responsibility Principle, which states that a class should only have a single responsibility. With that in mind there are probably very few cases where it makes sense to have 9 constructors.

足以完成其任务,但要记住单一责任原则,该原则规定一个班级应该只承担一项责任。考虑到这一点,可能很少有9个构造函数有意义的情况。

#9


I limit my class to only have one real constructor. I define the real constructor as the one that has a body. I then have other constructors that just delegate to the real one depending on their parameters. Basically, I'm chaining my constructors.

我限制我的类只有一个真正的构造函数。我将真正的构造函数定义为具有正文的构造函数。然后我有其他构造函数,根据它们的参数委托给真正的构造函数。基本上,我正在链接我的构造函数。

Looking at your class, there are four constructors that has a body:

看看你的班级,有四个构造函数有一个正文:

public MyManager(ISomeManager someManager) //this one I added
{
    this.someManager = someManager;
}

public MyManager(SomeClass someClass, DateTime someDate)
{
    if (someClass != null)
       myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
{
    myHelper = new MyHelper(someOtherClass, someDate, "some param");
}

public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
{
    myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
}

The first one is the one that you've added. The second one is similar to the last two but there is a conditional. The last two constructors are very similar, except for the type of parameter.

第一个是你添加的那个。第二个类似于最后两个,但有一个条件。除参数类型外,最后两个构造函数非常相似。

I would try to find a way to create just one real constructor, making either the 3rd constructor delegate to the 4th or the other way around. I'm not really sure if the first constructor can even fit in as it is doing something quite different than the old constructors.

我会尝试找到一种方法来创建一个真正的构造函数,使第三个构造函数委托给第四个或另一个方法。我不确定第一个构造函数是否可以适应,因为它正在做一些与旧构造函数完全不同的东西。

If you are interested in this approach, try to find a copy of the Refactoring to Patterns book and then go to the Chain Constructors page.

如果您对此方法感兴趣,请尝试查找Refactoring to Patterns一书的副本,然后转到Chain Constructors页面。

#10


Surely a class should have as many constructors as are required by the class... this doesnt mean than bad design can take over.

当然,一个班级应该有尽可能多的班级所需的构造函数......这并不意味着糟糕的设计可以接管。

Class design should be that a constructor creates a valid object after is has finished. If you can do that with 1 param or 10 params then so be it!

类设计应该是构造函数在完成后创建有效对象。如果你能用1个参数或10个参数做到这一点那么就这样吧!

#11


It seems to me that this class is used to do way, way to much. I think you really should refactor the class and split it into several more specialized classes. Then you can get rid of all these constructors and have a cleaner, more flexible, more maintainable and more readable code.

在我看来,这门课程已经习惯了。我认为你真的应该重构这个类并将它分成几个更专业的类。然后,您可以摆脱所有这些构造函数,并拥有更清晰,更灵活,更易于维护和更易读的代码。

This was not at direct answer to your question, but i do believe that if it is necessary for a class to have more than 3-4 constructors its a sign that it probably should be refactored into several classes.

这不是你问题的直接答案,但我确实认为,如果一个类有超过3-4个构造函数的必要性,那么它可能应该被重构为几个类。

Regards.

#12


The only "legit" case I can see from you code is if half of them are using an obsolete type that you are working to remove from the code. When I work like this I frequently have double sets of constructors, where half of them are marked @Deprecated or @Obsolete. But your code seems to be way beyond that stage....

我可以从您的代码中看到的唯一“合法”案例是,其中一半是使用您正在努力从代码中删除的过时类型。当我像这样工作时,我经常有两组构造函数,其中一半标记为@Deprecated或@Obsolete。但是你的代码似乎超出了那个阶段....

#13


I generally have one, which may have some default parameters. The constructor will only do the minimum setup of the object so it's valid by the time it's been created. If I need more, I'll create static factory methods. Kind of like this:

我通常有一个,可能有一些默认参数。构造函数只会对对象进行最小化设置,因此它在创建时有效。如果我需要更多,我将创建静态工厂方法。有点像这样:

class Example {
public:
  static FromName(String newname) { 
    Example* result = new Example();
    result.name_ = newname;
    return result;
  }
  static NewStarter() { return new Example(); }

private:
  Example();
}

Okay that's not actually a very good example, I'll see if I can think of a better one and edit it in.

好吧,这实际上并不是一个很好的例子,我会看看我是否能想到更好的一个并编辑它。

#14


The awnser is: NONE

awnser是:NONE

Look at the Language Dylan. Its has a other System.

看看语言迪伦。它有另一个系统。

Instat of a constructors you add more values to your slots (members) then in other language. You can add a "init-keyword". Then if you make a instance you can set the slot to the value you want.

构造函数的Instat可以为插槽(成员)添加更多值,然后使用其他语言。您可以添加“init-keyword”。然后,如果您创建实例,则可以将插槽设置​​为所需的值。

Ofcourse you can set 'required-init-keyword:' and there are more options you can use.

当然你可以设置'required-init-keyword:',​​你可以使用更多的选项。

It works and it is easy. I dont miss the old system. Writing constructors (and destructors).

它很有效,很容易。我不会错过旧系统。编写构造函数(和析构函数)。

(btw. its still a very fast language)

(顺便说一下,它仍然是一种非常快速的语言)


#15


I think that a class that has more than one constructor has more than one responsibility. Would be nice to be convinced about the opposite however.

我认为具有多个构造函数的类具有多个责任。不过很高兴相信相反的情况。