我正在重构一些遗留代码,这些代码通过case语句一遍又一遍地做同样的事情:
switch(identifier)
case firstIdentifier:
(SomeCast).SetProperties(Prop1,Prop2,Prop3);
break;
...
case anotherIdentifier:
(SomeDifferentCast).SetProperties(Prop1, Prop2, Prop3);
break;
所以,我尝试创建一个独特的界面,以便这可以成为
(SameInterfaceCast).SetProperties(Prop1,Prop2,Prop3);
然而,我发现有些项目甚至没有使用所有属性。所以,我开始想到更像这样的事情:
if(item is InterfaceForProp1)
(InterfaceForProp1).SetProp1(Prop1);
if(item is InterfaceForProp2)
(InterfaceForProp2).SetProp2(Prop2);
if(item is InterfaceForProp3)
(InterfaceForProp3).SetProp3(Prop3);
你可以创建一个这样的类:
public class MyClassUsesProp2And3 : InterfaceForProp2, InterfaceForProp3
但是,我担心我过度破坏了这段代码,而且它可能会过多。也许我不应该太害怕什么本质上是一个方法接口,但我想看看我是否缺少一个设计模式在走这条路径之前? (唯一出现在我脑海中但不太合适的是Decorator或Composite模式)
更新
所有属性都是唯一类型。
最终,这是依赖注入的一种形式。代码太乱了,现在使用像Ninject这样的东西,但最终我甚至可以摆脱其中一些并使用注射容器。除了设置变量之外,目前还有一些逻辑正在完成。这是所有遗留代码,我只想一点一点地清理它。
答案 0 :(得分:1)
我不知道这是否有“正确”的答案,但这就是我要做的。
class Properties {
prop1
prop2
prop3
}
interface PropertySetable {
setProperties(Properties prop);
}
public class MyClassUsesProp2And3 implements PropertySetable {
setProperties(Properties prop) {
//I know I need only 2 and 3
myProp2 = prop.prop2;
myProp3 = prop.prop3;
}
}
在调用函数时,你不应该有一个强制转换。
someFunc(..., PropertySetable, Properties,...) {
PropertySetable.setProperties(Properties);
}
这是基本结构。
您应该封装属性 - 将属性设为私有并具有相关的构造函数。或者使用Builder模式构建属性......以及更多......
答案 1 :(得分:1)
我认为答案取决于你想要首先重构代码的原因。
答案 2 :(得分:1)
当您遇到switch语句和类型转换时,visitor pattern是标准解决方案。每个案例的代码将在访问者类中进入单独的方法。并且您的每个类都将只实现一个接口 - accept
方法来接受访问者。你将获得比现在更多的代码,但它会读得更清晰。
答案 3 :(得分:1)
基本上你想让actor(使用setProp方法输入)使用相同类型的'Actor'并使属性(prop1 ... n)成为同一类型'Prop'。这会将您的代码减少到
actor.setProp(prop)
如果你想避免使用instanceOf,我唯一能想到的方法是使用访问者模式,让'Prop'成为访问者。我也会使用模板方法让我的生活更轻松。在Java中,我会使它看起来像这样(对于两种实际的Prop)。
class Actor {
protected void set(Prop1 p1) {
// Template method, do nothing
}
protected void set(Prop2 p2) {
// Template method, do nothing
}
public void setProp(Prop p) {
p.visit(this);
}
public interface Prop {
void visit(Actor a);
}
public static Prop makeComposite(final Prop...props ) {
return new Prop() {
@Override
public void visit(final Actor a) {
for (final Prop p : props) {
p.visit(a);
}
}
};
}
public static class Prop1 implements Prop {
public void visit(Actor a) {
a.set(this);
}
}
public static class Prop2 implements Prop {
public void visit(Actor a) {
a.set(this);
}
}
}
这允许你做这样的事情:
ConcreteActor a = new ConcreteActor();
Prop p = Actor.makeComposite(new ConcreteProp1(42), new ConcreteProp2(-5));
a.setProp(p);
......这太棒了!