Implementation of factory method in related class hierarchies
请参见代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | class X { public string x; } class Y : X { public string y; } class A { string a; public virtual X createX<T>() where T : X, new() { return new T() { x = a }; } } class B : A { string b; public override X createX<T>() { var x = base.createX<T>(); if (x is Y) ((Y)x).y = b; // Yak. return y; } } ... var c = new B(); var z = c.createX<Y>(); // Yak. I prefer to not needing to know the type Y |
我不喜欢这段代码,试图想出更好的方法来重构它。一般的想法很简单,层次结构的每个类都有工厂方法来生成镜像层次结构对应类的实例。我得到一个根类或派生类的实例,需要返回对应类或其派生类的实例(作为根对应类)。我有什么想法或者设计模式可以代替吗?
这就是我的结局。所有游艇都已移除。但有点冗长。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | class X { public string x; } class Y : X { public string y; } class A { string a; protected void setX(X x) { x.x = a; } public virtual X createX() { var x = new X(); setX(x); return x; } } class B : A { string b; protected void setY(Y y) { base.setX(y); y.y = b; } public override X createX() { var y = new Y(); setY(y); return y; } } ... var c = new B(); var z = c.createX(); |
号
这是你想要的吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | class BaseProduct { public string x; } class ChildProduct : BaseProduct { public string y; } class BaseFactory { string a; public virtual BaseProduct buildProduct(BaseProduct product = null) { if (product == null) product = new BaseProduct(); product.x = a; return product; } } class ChildFactory : BaseFactory { string b; public override BaseProduct buildProduct(BaseProduct product = null) { if (product == null) product = new ChildProduct(); //else if (!(product is ChildProduct)) // return null or throw exception ((ChildProduct)product).y = b; return base.buildProduct(product); //build BaseProduct.x } } ... var cFactory = new ChildFactory(); var cProduct = c.buildProduct(); //create a ChildProduct with x=a, y=b |
buildProduct determine whether it has been requested to create a new
product of its own, or some derived-factory requesting it to build its
own part onlyYou should provide some safeguard mechanism of your own, like checking
whether the product is a derived class from ChildProduct in
ChildFactory.buildProduct. That'll avoid user from passing something like:
childFactory.buildProduct(new BaseProduct()); //yak
号