public interface ButtonFactory {
Button createButton();
}
public class IosButtonFactory implements ButtonFactory {
public Button createButton() {
return new IosButton();
}
}
public class AndroidButtonFactory implements ButtonFactory {
public Button createButton() {
return new AndroidButton();
}
}
现在。如果你必须提供一个新的按钮类型,你只需要像这样添加一个新的实现:
public class WindowsButtonFactory implements ButtonFactory {
public Button createButton() {
return new WindowsButton();
}
}
1条答案
按热度按时间mspsb9vt1#
打开/关闭原则并不意味着您不能更改工厂代码。它要求您只扩展,而不修改工厂的接口和行为。
然而,像这样实现Abstract Factory Pattern将最接近您的愿望:
现在。如果你必须提供一个新的按钮类型,你只需要像这样添加一个新的实现:
这样,你的工厂就没有条件语句了。
考虑到必须有一个位置,其中一个条件决定使用与所提供的
string os
相关的具体实现。这可以在你的 Bootstrap 中,在那里你配置你的IoC容器,或者在你的main方法中,如这个非常简洁的sample所示。这样,你的工厂就没有条件语句了,就像你最初的问题所要求的那样。
工厂模式还有其他一些设计,但是,它不再是抽象工厂,而是简单工厂。
在这里,我们再次从接口开始:
实现可能看起来像这样:
阅读this article以了解为什么token必须是原始数据类型。
这种设计符合OpenClosed原则,因为一旦引入了上面提到的WindowsButton,您只需扩展而无需修改代码。
如果你喜欢,并且不需要考虑速度和其他缺点,你可能想使用反射:
首先,创建一个新的注解:
我们的工厂可能看起来像这样:
现在,如果您必须为@Token("windows")扩展一个新的私有方法,则不再需要调整任何分派代码,如switch/if或Map初始化。但是,如上所述,反射有一些严重的影响需要考虑。保重,祝你好运。
(免责声明:上面的代码未经测试,可能需要一些小的更改才能运行。为了便于阅读和理解,它不包含错误处理。)