vic*_*cky 6 java design-patterns software-design factory-pattern
我正在新学习设计模式,我试图理解简单工厂和工厂方法模式之间的区别。首先我想澄清一下,我尝试阅读 Stack-overflow 和其他网站上的大量相关文章,但这对我没有帮助。
我写了一个简单的工厂类,如下所示
public class SimpleItemFactory {
static Item getItem(String type) {
if(type.equals("Cake")) {
return new Cake();
}else if(type.equals("Chocolate")) {
return new Chocolate();
}else {
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以现在我将所有对象创建都集中在一处,因此如果明天发生任何更改[例如构造函数需要一个参数],我们只需在一处进行更改。但它打破了 OPEN CLOSED 原则,就好像明天我们添加更多项目,我们需要更改 getItem() 方法(如果条件)。所以我们选择工厂方法模式

我们创建Factory类如下所示:
public abstract class ItemFactory {
abstract Item getItem();
}
class CakeFactory extends ItemFactory {
@Override
Item getItem() {
return new Cake();
}
}
class ChocolateFactory extends ItemFactory {
@Override
Item getItem() {
return new Chocolate();
}
}
class Client{
public static void main(String[] args) {
Item chocolate = new ChocolateFactory().getItem();
System.out.println(chocolate);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当客户想要添加名为 IceCream 的新项目时,他们只需创建名为 IceCreamFactory 的新工厂并从中创建 IceCream ,如下所示:
class IceCreamFactory extends ItemFactory{
@Override
Item getItem() {
return new IceCream();
}
}
class Client{
public static void main(String[] args) {
Item iceCream = new IceCreamFactory().getItem();
System.out.println(iceCream);
}
}
Run Code Online (Sandbox Code Playgroud)
我的理解正确吗? 我们在这里满足了开放封闭原则,但是对于每个产品(Item)我们需要一个Factory类,这不是成为可管理的噩梦吗?
您的理解实际上是正确的,只是您需要注意,每种设计模式都是为了解决至少一个问题,有时它可能会带来一些其他复杂性或副作用,这意味着没有完美的设计模式可以解决所有问题问题。
出于学习目的,您将逐一应用设计模式(这使得设计模式的真正威力同样被害羞或隐藏),但是在现实世界中,设计模式混合在一起(或者甚至您可以发明一种新的:p)为了创建最能满足您的需求并接近理想的东西,您可以遇到例如将 Builder 模式与 Factory 模式混合或将 Factory 模式与策略模式混合,甚至将这三种模式混合在一起......
对于您在这里的情况,我建议例如使用工厂方法模式与简单工厂模式结合依赖注入模式来创建一些完全漂亮的东西,同时满足开放封闭原则。
class ItemFactoryContainer() {
private Map<String, ItemFactory> factories = new HashMap<>();
public void register(String name, ItemFactory factory) {
factories.put(name, factory);
}
public ItemFactory getFactory(String name) {
return factories.get(name);
}
}
public class ItemFactoryTest {
public static void main(String...args) {
ItemFactoryContainer factoryContainer = new ItemFactoryContainer();
factoryContainer.register("choclate", new ChocolateFactory ());
factoryContainer.register("cake", new CakeFactory ());
factoryContainer.register("iceCream", new IceCreamFactory ());
Chocolate choclate = factoryContainer.getFactory("choclate").getItem();
Cake cake = factoryContainer.getFactory("cake").getItem();
}
}
Run Code Online (Sandbox Code Playgroud)