简单工厂的缺点:对开闭原则的支持不够,如果有新的产品加入系统中,就需要修改工厂类,将必要的逻辑加入工厂类中。
工厂方法模式是简单工厂模式的进一步抽象和推广,使用了多态,工厂方法模式保持了简单工厂的优点,并克服了他的缺点。核心的工厂类不再负责所有产品的创建,将具体创建的工作交给子类,核心类成为抽象工厂,负责给出具体工厂子类必须实现的接口
这种模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品。只需要像系统加入一个这个产品类和对应的工厂类
概述
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让实例化推迟到子类。
Product:抽象产品。所有的产品必须实现这个共同的接口,这样一来,使用这些产品的类既可以引用这个接口。而不是具体类。
ConcreteProduct:具体产品。
Creator:抽象工厂。它实现了所有操纵产品的方法,但不实现工厂方法。Creator所有的子类都必须要实现factoryMethod()方法。
ConcreteCreator:具体工厂。制造产品的实际工厂。它负责创建一个或者多个具体产品,只有ConcreteCreator类知道如何创建这些产品。
工厂方法模式是简单工厂模式的延伸。在工厂方法模式中,核心工厂类不在负责产品的创建,而是将具体的创建工作交给子类去完成。也就是后所这个核心工厂仅仅只是提供创建的接口,具体实现方法交给继承它的子类去完成。当我们的系统需要增加其他新的对象时,我们只需要添加一个具体的产品和它的创建工厂即可,不需要对原工厂进行任何修改,这样很好地符合了“开闭原则”。
abstract class Pizza{ protected String name; protected List<String> toppings = new ArrayList<>(); public void parpare() { System.out.println("parpare " + name); Iterator<String> it = toppings.iterator(); while (it.hasNext()) { System.out.println(" " + it.next()); } } public void box() { System.out.println("pizza box"); } public String getName() { return name; } } class NYStyleCheesePizza extends Pizza{ public NYStyleCheesePizza(){ name = "Ny Style Sauce and Cheese Pizza"; toppings.add("Crated Reggiano Cheese"); } } class ChicagoStyleCheesePizza extends Pizza { public ChicagoStyleCheesePizza(){ name = "Chicago Style Deep Dish Cheese Pizza"; toppings.add("Shredded Mozzarella Cheese"); } } abstract class PizzaStore{ public Pizza orderPizza(String type){ Pizza pizza; pizza = createPizza(type); pizza.parpare(); pizza.box(); return pizza; } abstract Pizza createPizza(String type); } class NyPizzaStore extends PizzaStore{ @Override Pizza createPizza(String type) { if (type.equals("cheese")){ return new NYStyleCheesePizza(); } else if (type.equals("green")){ return new ........ } } } class ChicagoStore extends PizzaStore{ @Override Pizza createPizza(String type) { if (type.equals("cheese")){ return new ChicagoStyleCheesePizza(); } else if (type.equals("green")){ return new ....... } } }
优点
1、 在工厂方法中,用户只需要知道所要产品的具体工厂,无须关系具体的创建过程,甚至不需要具体产品类的类名。
2、 在系统增加新的产品时,我们只需要添加一个具体产品类和对应的实现工厂,无需对原工厂进行任何修改,很好地符合了“开闭原则”。
缺点
1、 每次增加一个产品时,都需要增加一个具体类和对象实现工厂,是的系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
七、总结
1、工厂方法模式完全符合“开闭原则”。
2、工厂方法模式使用继承,将对象的创建委托给子类,通过子类实现工厂方法来创建对象。
3、工厂方法允许类将实例化延伸到子类进行。
4、工厂方法让子类决定要实例化的类时哪一个。在这里我们要明白这并不是工厂来决定生成哪种产品,而是在编写创建者类时,不需要知道实际创建的产品是哪个,选择了使用哪个子类,就已经决定了实际创建的产品时哪个了。
5、在工厂方法模式中,创建者通常会包含依赖于抽象产品的代码,而这些抽象产品是、由子类创建的,创建者不需要真的知道在制作哪种具体产品。