【发布时间】:2015-02-24 05:49:44
【问题描述】:
一般来说,在构造函数中构造其他对象是不是一个坏主意(我通常不喜欢它)?假设 A 类型的对象需要 B 类型的实例。B 类型的实例应该是静态的,因为我真的只想要它的一个副本……真的……不,说真的。类型 b 还会引发类型 A 需要处理的事件。 B 型位于我无法控制的外部库中。使我的 B 类对象成为静态对象似乎对测试来说是一件烦人的事情。我最初想让 A 完全静态,因为它本质上是 B 的代理。也许这才是真正的问题。当被代理的对象需要初始化时,什么是好的代理设计?我能想到至少三个选项:
- 传入参数需要构造类型 A 和类型 B。 然后类型 A 的构造函数构造类型 B。(调用 create 方法从构造函数中返回类型 B 将是相同的基本概念。
- 传入一个构造对象。
- 创建一个初始化方法。
我不喜欢选项 1,因为它太复杂了。我将不得不做各种类型的 B 初始化代码,设置事件处理程序等。 我不喜欢选项 2,因为我不希望外界知道这种依赖关系。 A 类是唯一会与 B 类交互的类型。 一般来说,我不喜欢初始化方法,或“保护”封装依赖项状态的方法。我似乎最终得到了很多这样的代码:
if (typeB != null && typeB.State != Unitialized)
哎呀。
这是我正在使用的一些示例代码。只是在寻找如何使它真正干净、简单和易于维护。
public class A
{
private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private B b;
public new A(string productName, string serviceName)
{
b = new B
{
ProductName = productName,
ServiceName = serviceName
};
b.SomethingHappened += b_HandleIt;
更新: 我在对答案的评论中引用了this pragmatic article。我熟悉 DI、IoC、工厂方法、构建器模式、构造函数注入、方法注入、属性注入、测试驱动设计等。我想我的问题是,如何在尽可能少编码的同时平衡简单性和良好设计并尽可能快地满足我目前的需求? B 类永远不会被替换,我没有理由相信除了 A 类之外的任何东西都会在我的项目中使用 B 类。我有点担心测试的接缝,但是A类很简单,代码很少,基本上是封装了一个第三方类。
【问题讨论】:
-
依赖对象应该在构造时传入/注入到对象中。使用工厂方法来封装需要大量依赖项的复杂对象构造。构造函数签名指的是接口而不是具体的。
-
我了解您对选项 2 的问题,但这些都是错误的担忧。看看依赖注入,例如codeproject.com/Articles/615139/… 选项 2(传入构造的对象)在我看来是要走的路。
-
essentials.xebia.com/kiss 怎么样?这些类不需要多态性,我希望它们紧密耦合。为什么这些担忧是错误的?
标签: c# oop design-patterns constructor proxy-pattern