我尝试理解SOLID原则,因此实现了一些java片段。我关注的是目前的OCP。有以下样本,
Reset
如何创建合适的面包店。假设顾客来到面包店并说:“我有两个蛋糕,拜托!”,我怎么能实例化CakeBakery。当然,我可以创建一个抽象工厂,如:
public abstract class Bakery
{
public abstract Bakegood bake();
}
/******************************************/
public class BreadBakery extends Bakery {
@Override
public Bakegood bake() {
return new Bread();
}
}
/******************************************/
public class CakeBakery extends Bakery {
@Override
public Bakegood bake() {
return new Cake();
}
}
/******************************************/
但我不想使用switch或if语句。还有其他可能性,还是我完全错误理解?
答案 0 :(得分:3)
开放/封闭原则说:
软件实体(类,模块,函数等)应该是开放的 用于扩展,但已关闭以进行修改。
因此,无论何时引入新的面包店,都不应修改现有代码。您可以在Bakery类中使用类似注册表的内容。如果您需要添加一个新的Bakery,只需扩展Bakery类并注册它(例如在启动时)。因此,不需要“if”或“switch”修改。此外,添加新的Bakery不需要更改注册表的内部或调用注册表的代码。
此外,此技术不依赖于您注册组件的方式。您可以使用配置文件(xml,...),通过类路径扫描,以编程方式执行...
你可以在Spring框架中看到很多这种方法。基本上,Spring框架是许多设计原则的重要来源。
在这里,您可以看到一个非常简单的注册表实现。
public class BakeryRegistry {
private Map<String, Bakery> mapping = new HashMap<>();
public BakeryRegistry() {
loadDefaultMappingFromConfigFile();
}
public Bakery getBakery(String name) {
return mapping.get(name);
}
public void registerBakery(String name, Bakery bakery) {
mapping.put(name, bakery);
}
private void loadDefaultMappingFromConfigFile() {
...
}
}
也许文章Killing Switch Statements With A Registry可以提供帮助。它基于JavaScript,但原理是相同的。
答案 1 :(得分:0)
设计抽象导致了这里的问题。客户不会向面包店询问抽象的烘焙食品,因为所有烘焙食品都不可替代。面包不是蛋糕的替代品,反之亦然。将这两种不同的产品包装成一个继承层次结构违反了Liskov替代原则。
SOLID原则是相互关联的,因此如果不首先应用LSP,则难以或不可能应用OCP。请参阅introduction to LSP,其中Robert Martin将继承描述为对OCP至关重要,并继续将LSP描述为继承的关键。