【发布时间】:2016-09-13 07:20:51
【问题描述】:
我的程序有两个类;两者都派生自同一个基类。
class A : MyBase
{
internal A(InitVal initVal)
}
class B : MyBase
{
internal B(InitVal initVal)
}
InitVal 是另一个通过构造函数注入的类。此类供内部使用。由于内部构造函数,用户无法直接创建类A 和B 的实例。相反,我创建了创建这些对象的方法。
class Initiator
{
InitVal initVal;
public T CreateObject<T>(ObjectInstance objectInstance) where T : MyBase
{
MyBase myBase = null;
switch(objectInstance)
{
case ObjectInstance.A:
myBase = new A(initVal);
break;
case ObjectInstance.B:
myBase = new B(initVal);
break;
}
return (T)myBase;
}
...
}
ObjectInstance 是上面代码中的枚举。
这没有问题,但我相信你以前从未见过如此丑陋的代码。
请建议我应该使用的创作模式。我想删除 ObjectInstance 枚举而不更改功能。它会清理很多。
我尝试了dotfactory 中提到的Creational Patterns。
Factory Method 和 Abstract Factory 在这种情况下看起来不合适。
我的代码虽然看起来很丑,但读起来很简单。我尝试实现上述增加代码复杂性的模式。所以这也是我选择答案的标准。
除了Initiator 类之外,我无法更改代码中的任何内容。我无法访问所有其他类进行编辑。
编辑 1:为什么上面的代码在我看来很难看
1) 在调用CreateObject 方法时,用户必须两次指定对象的类型。
A a = initiator.CreateObject<A>(ObjectInstance.A);
首先是T 通用值,其次是枚举值。
我想避免这种情况。
2) 由于用户必须两次指定对象类型,因此有可能出错。
A a = initiator.CreateObject<A>(ObjectInstance.B);
在上面的代码中,枚举值和通用值是不同的。 这是不允许的,这将是一个问题。 使用我的代码,我无法避免这种情况。
这就是为什么;我正在寻找适合我的情况而又不增加复杂性的模式。
如果我以某种方式消除枚举的必要性,代码会好得多。
如果我能把CreateObject的签名改成关注就更好了。
public T CreateObject<T>() where T : MyBase
但是,我不确定如何实现这个方法来创建合适的实例。
【问题讨论】:
-
如果您无法更改
A或B,那么人们仍然可以创建A和/或B的实例。那为什么还要打扰整个Initiator类呢? -
如果您不希望 API 的使用者实例化类,我会将构造函数设为内部
-
您的代码并没有那么难看,这正是工厂方法所做的:它根据某些不同的值创建类型的实例,在您的情况下是 enum。如果添加了新类,您也可以通过配置文件执行此操作,而不必更改源代码。只有真正丑的是你的缩进。
-
当前
Initiator类的一个问题是用户现在必须构造Initiator的实例,并且必须以某种方式设置initVal。字段是如何设置的? -
另一种方式,更简洁的方法是简单地使用 2 种方法来创建 A 或 B,第 3 方方法将选择其中一种。或者将其作为一种方法实现,并通过指定泛型类型来决定类型。否则它只是一个工厂方法,它看起来很好。 PS。将启动器设为静态,并将 initVal 设为最有可能的参数:P
标签: c# design-patterns creation-pattern