构造函数:完全成熟还是最小化?

rlu*_*uba 2 language-agnostic oop constructor

在设计课程时,您通常需要做出以下决定:

  • 提供一个"完整"构造函数,它将所有必需字段的初始值作为参数:使用笨拙但保证完全初始化和有效的对象
  • 为所有必要字段提供"默认"构造函数和访问器:有时可能很方便,但不保证在调用某些关键方法之前所有成员都已正确初始化.
  • 混合方法(更多代码,更多工作,可以'消除"未完全初始化"的问题)

我已经看到了几个API和框架使用上述之一甚至是不一致的方法,这种方法因类而异.您对该主题有何看法和最佳做法?

Tho*_*ung 7

简短的回答是,在调用构造函数之后,应该对对象进行完全初始化.

这应该是默认方法,对用户来说意外最少.在某些情况下,您的运行时,框架或其他技术限制会阻止默认方法.

在某些情况下,Builder模式有助于在无法使用简单构造函数时支持案例.这种方法处于中间位置,允许用户调用setter进行初始化,并且仍然只能使用完全初始化的对象.

一个静态工厂方法时对象的构造需要比一个构造更灵活,但是建设者是太复杂,实现在适当的情况下.

构造函数:

x = new X(a, b);
Run Code Online (Sandbox Code Playgroud)

二传手:

x = new X();
x.setA(a);
x.setB(b);
Run Code Online (Sandbox Code Playgroud)

生成器:

builder = new Builder();
builder.setA(a);
builder.setB(b);
x = builder.build();
Run Code Online (Sandbox Code Playgroud)

静态工厂方法:

x = X.newX(a, b);
Run Code Online (Sandbox Code Playgroud)

所有四种方法都将产生X类的实例x.

构造函数

优点:

  • 简单

缺点:

  • 由于限制可能无法实现
  • 可能需要太多的构造函数的参数(命名参数和默认值可以帮助这里,如果语言支持他们:new X(a = "a", b = "c"))

二传手

优点:

  • 适度的复杂性
  • 可以由框架强制执行

缺点:

  • 实例可能未完全初始化

生成器

优点:

  • 最灵活的方法
  • 可以重用实例(在内部使用单例,flyweights和缓存)

缺点:

  • 最复杂的实施
  • 可能会为无效的初始化对象生成运行时异常
  • 构建器对象实例的开销

静态工厂方法

优点:

  • 适度的复杂性
  • 可以重用实例(在内部使用单例,flyweights和缓存)

缺点:

  • 实现和使用比构造函数更复杂