Questions tagged «constructors»

9
为什么要使用工厂类而不是直接对象构造?
我已经在GitHub和CodePlex上看到了几个С#和Java类库项目的历史,并且看到了切换到工厂类而不是直接对象实例化的趋势。 为什么要广泛使用工厂类?我有一个很好的库,通过老式的方式创建对象-通过调用类的公共构造函数。在最后的提交中,作者迅速将所有数千个类的公共构造函数更改为内部构造,并且还创建了一个具有数千个CreateXXX静态方法的巨大工厂类,这些静态方法通过调用类的内部构造函数来返回新对象。外部项目API损坏了,做得很好。 为什么这样的更改有用?用这种方式重构的目的是什么?用静态工厂方法调用替换对公共类构造函数的调用有什么好处? 什么时候应该使用公共构造函数,什么时候应该使用工厂?

12
有没有理由在构造函数中完成所有对象的工作?
首先,我说这不是我的代码也不是我的同事的代码。几年前,当我们的公司规模较小时,我们有一些我们需要做的项目,但我们没有能力,因此将它们外包了。现在,我一般都不会反对外包或承包商,但是他们产生的代码库是大量的WTF。话虽这么说,它确实(大部分)有效,所以我认为它在我所见过的外包项目中排名前10%。 随着我们公司的成长,我们尝试将更多的内部开发工作带入公司。这个特殊的项目落在我的腿上,所以我一直在检查,清理,添加测试等。 我看到有一种模式经常重复出现,而且看起来如此令人恐惧,以至于我想知道是否存在某种原因,而我只是看不到它。模式是一个没有公共方法或成员的对象,只是一个公共构造函数,它可以完成对象的所有工作。 例如,(如果很重要,代码是Java的,但是我希望这是一个更普遍的问题): public class Foo { private int bar; private String baz; public Foo(File f) { execute(f); } private void execute(File f) { // FTP the file to some hardcoded location, // or parse the file and commit to the database, or whatever } } 如果您想知道,这种类型的代码通常以以下方式调用: for(File f …

7
在构造函数中使用“ new”总是不好吗?
我已经读到,在构造函数中使用“ new”(对于除简单值对象之外的任何其他对象)是一种不好的做法,因为它使单元测试变得不可能(因为这些协作者也需要创建并且不能被模拟)。由于我没有真正的单元测试经验,因此我试图收集一些我将首先学习的规则。另外,无论使用哪种语言,这是一条通常有效的规则吗?

9
C#中的构造函数参数验证-最佳做法
构造函数参数验证的最佳实践是什么? 假设有一个简单的C#: public class MyClass { public MyClass(string text) { if (String.IsNullOrEmpty(text)) throw new ArgumentException("Text cannot be empty"); // continue with normal construction } } 抛出异常是否可以接受? 我遇到的替代方法是在实例化之前进行预验证: public class CallingClass { public MyClass MakeMyClass(string text) { if (String.IsNullOrEmpty(text)) { MessageBox.Show("Text cannot be empty"); return null; } else { return new …

5
我应该通过参数还是通过返回值初始化C结构?[关闭]
我工作的公司正在通过初始化函数来初始化所有数据结构,如下所示: //the structure typedef struct{ int a,b,c; } Foo; //the initialize function InitializeFoo(Foo* const foo){ foo->a = x; //derived here based on other data foo->b = y; //derived here based on other data foo->c = z; //derived here based on other data } //initializing the structure Foo foo; InitializeFoo(&foo); 我遇到了一些尝试初始化我的结构的问题: …

3
“开始”,“运行”或“执行”方法是一种好习惯吗?
我目前正在开发具有许多实现Start方法的类的代码库。在我看来,这似乎是两阶段构建,我一直认为这是一种不良做法。我不能说这和构造函数之间的区别。 什么时候适合使用start方法而不是普通的对象构造方法? 我何时应该更喜欢使用构造函数? 编辑:我不认为这是相关的,但是编程语言是C#,它同样适用于Java或C ++

3
可选参数或重载的构造函数
我正在实现DelegateCommand,当我要实现构造函数时,我想到了以下两种设计选择: 1:具有多个重载的构造函数 public DelegateCommand(Action<T> execute) : this(execute, null) { } public DelegateCommand(Action<T> execute, Func<T, bool> canExecute) { this.execute = execute; this.canExecute = canExecute; } 2:只有一个带有可选参数的构造函数 public DelegateCommand(Action<T> execute, Func<T, bool> canExecute = null) { this.execute = execute; this.canExecute = canExecute; } 我不知道使用哪个,因为我不知道这两种建议的方式都有哪些优点/缺点。两者都可以这样称呼: var command = new DelegateCommand(this.myExecute); var command2 = …

5
为什么在构造函数中使用setter并没有成为常见的模式?
访问器和修饰符(又名setter和getter)之所以有用,主要有以下三个原因: 它们限制了对变量的访问。 例如,可以访问但不能修改变量。 他们验证参数。 它们可能会引起一些副作用。 大学,在线课程,教程,博客文章和Web上的代码示例都在强调访问器和修饰符的重要性,如今,它们几乎像是代码的“必备”。因此,即使它们不提供任何附加值,也可以找到它们,例如下面的代码。 public class Cat { private int age; public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } } 话虽如此,找到更有用的修饰符是很常见的,这些修饰符实际上会验证参数并抛出异常,或者如果提供了无效输入,则返回布尔值,如下所示: /** * Sets the age for the current cat * @param age an integer with the valid values between …

4
在构造函数中合法的“实际工作”?
我正在设计,但是一直遇到障碍。我有一个特定的类(ModelDef),它实际上是通过解析XML模式(例如DOM)构建的复杂节点树的所有者。我想遵循良好的设计原则(SOLID),并确保生成的系统易于测试。我打算使用DI来将依赖项传递到ModelDef的构造函数中(以便在测试过程中可以根据需要轻松地将其替换掉)。 不过,我正在努力的是创建节点树。该树将完全由简单的“值”对象组成,而这些对象无需独立测试。(但是,我仍然可以将抽象工厂传递到ModelDef中,以帮助创建这些对象。) 但是我一直在读,构造函数不应该做任何实际的工作(例如Flaw:Constructor可以进行实际工作)。如果“实际工作”意味着构造重量较重的相关对象,而以后可能希望将其存根进行测试,则这对我来说非常有意义。(这些应通过DI传递。) 但是像该节点树这样的轻量级对象呢?必须在某个地方创建树,对不对?为什么不通过ModelDef的构造函数(例如使用buildNodeTree()方法)呢? 我真的不想在ModelDef之外创建节点树,然后再通过(通过构造函数DI)将其传递进去,因为通过解析架构来创建节点树需要大量复杂的代码-需要进行彻底测试的代码。我不想将其委托给“胶合”代码(这应该是相对琐碎的,并且可能不会被直接测试)。 我曾考虑过将代码创建节点树放在一个单独的“构建器”对象中,但是犹豫称它为“构建器”,因为它与“构建器模式”并不完全匹配(后者似乎与消除伸缩无关。构造函数)。但是,即使我将其称为其他名称(例如NodeTreeConstructor),也只是为了避免让ModelDef构造函数构建节点树而感到有些破绽。它必须建在某个地方。为什么不在要拥有它的对象中?

5
如何分解构造函数?
可以说我有一个Enemy类,构造函数如下所示: public Enemy(String name, float width, float height, Vector2 position, float speed, int maxHp, int attackDamage, int defense... etc.){} 这看起来很糟糕,因为构造函数有很多参数,但是当我创建一个Enemy实例时,我需要指定所有这些内容。我还希望在Enemy类中具有这些属性,以便可以遍历它们的列表并获取/设置这些参数。我当时想也许可以将Enemy子类化为EnemyB,EnemyA,同时对它们的maxHp和其他特定属性进行硬编码,但是如果我想遍历一个Enemy列表(由EnemyA,EnemyB和EnemyC)。 我只是想学习如何干净地编码。如果有所作为,我将使用Java / C ++ / C#。朝正确方向的任何观点表示赞赏。

3
大量参数的构造函数与构造器模式
众所周知,如果您的类的构造函数带有许多参数,例如超过4个,则很可能是代码气味。您需要重新考虑该类是否满足SRP要求。 但是,如果我们构建并反对依赖10个或更多参数的对象,并最终通过Builder模式设置所有这些参数,该怎么办?想象一下,您Person用其个人信息,工作信息,朋友信息,兴趣信息,教育信息等构建了一个类型对象。这已经很好了,但是您可以通过多个4来设置相同的参数,对吗?为什么这两种情况不一样?

3
构造函数应该有多复杂
我正在与我的同事讨论一个构造函数可以完成多少工作。我有一个类B,它内部需要另一个对象A。对象A是类B需要完成其工作的几个成员之一。它的所有公共方法都依赖于内部对象A。有关对象A的信息存储在DB中,因此我尝试通过在构造函数中的DB上进行查找来进行验证和获取。我的同事指出,除了捕获构造函数参数外,构造函数不应做太多工作。由于如果使用构造函数的输入未找到对象A,所有公共方法都将失败,因此我认为与其允许创建实例并在以后失败,不如让它早于构造器。 别人怎么想?如果这有任何区别,我正在使用C#。 阅读是否有理由在构造函数中完成对象的所有工作?我想知道通过转到DB来获取对象A是“使该对象准备好使用所需的任何其他初始化”的一部分,因为如果用户将错误的值传递给构造函数,我将无法使用其任何公共方法。 构造函数应实例化对象的字段,并进行其他任何必要的初始化,以使对象可以立即使用。这通常意味着构造函数很小,但是在某些情况下这将需要大量的工作。
18 c#  constructors 

1
使默认构造函数不可用就可以了吗?
具体询问默认构造函数 考虑到构造函数会初始化一个对象的所有数据,如果我创建了一个未经适当初始化就无法使用的类,那么默认构造函数是否就没有用?考虑: // A class for handling lines in a CSV file class CSV_Entry { private: unsigned num_entries; std::string string_version; std::vector<std::string> vector_version; ...etc public: CSV_Entry(); CSV_Entry(const std::string& src_line); // returns a vector copy of the original entry std::vector<std::string> get_vector_snapshot(); } int main( void ) { ...etc CSV_Entry example = CSV_Entry(); …

3
如何使参数保持低计数并仍保持第三方依存关系独立?
我使用第三方图书馆。他们向我传递了一个POJO,出于我们的意图和目的,可能是这样实现的: public class OurData { private String foo; private String bar; private String baz; private String quux; // A lot more than this // IMPORTANT: NOTE THAT THIS IS A PACKAGE PRIVATE CONSTRUCTOR OurData(/* I don't know what they do */) { // some stuff } public String getFoo() { …

2
单元测试以测试域对象的创建
我有一个单元测试,如下所示: [Test] public void Should_create_person() { Assert.DoesNotThrow(() => new Person(Guid.NewGuid(), new DateTime(1972, 01, 01)); } 我声称这里创建了一个Person对象,即验证不会失败。例如,如果Guid为null或生日早于01/01/1900,则验证将失败并且将引发异常(意味着测试失败)。 构造函数如下所示: public Person(Id id, DateTime dateOfBirth) : base(id) { if (dateOfBirth == null) throw new ArgumentNullException("Date of Birth"); elseif (dateOfBith < new DateTime(1900,01,01) throw new ArgumentException("Date of Birth"); DateOfBirth = dateOfBirth; } 这是测试的好主意吗? 注意:我遵循经典方法对单元模型进行单元测试(如果有)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.