工厂设计模式的定义(what)
参考:
https://www.runoob.com/design-pattern/factory-pattern.html
https://www.runoob.com/design-pattern/abstract-factory-pattern.html
工厂: 顾名思义类似产品、食品等的一类事物生产的工厂。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象
组成:
- 工厂 用来创建产品
- 产品 实现不同种类的产品
工厂设计模式的多种实现(how)
简单工厂
特点: 将产品进行抽象
优点:实现简单, 比较容易理解
缺点: 扩展除了需要新增产品, 也需要修改工厂类。
-
抽象类-披萨产品类
package com.arithmetic.gof.factory.product; /** * 产品-披萨 * * @author mazhiyuan * @date 2022/02/21 */ public abstract class Pizza { /** * 产品名字 */ protected String name; /** * 披萨的味道 */ public abstract void pizzaTaste(); public void setName(String name) { this.name = name; } }
-
具体不同的产品类
package com.arithmetic.gof.factory.product; /** * 芝士披萨 * * @author mazhiyuan * @date 2022/02/21 */ public class CheesePizza extends Pizza { @Override public void pizzaTaste() { System.out.println("给制作芝士披萨"); } }package com.arithmetic.gof.factory.product;
package com.arithmetic.gof.factory.product; /** * 希腊披萨 * * @author mazhiyuan * @date 2022/02/21 */ public class GreekPizza extends Pizza { @Override public void pizzaTaste() { System.out.println(" 给制作希腊披萨"); } }
package com.arithmetic.gof.factory.product; /** * 胡椒披萨 * * @author mazhiyuan * @date 2022/02/21 */ public class PepperPizza extends Pizza { @Override public void pizzaTaste() { System.out.println("给制作胡椒披萨"); } }
-
制作/创建工厂类
package com.arithmetic.gof.factory; import com.arithmetic.gof.factory.product.CheesePizza; import com.arithmetic.gof.factory.product.GreekPizza; import com.arithmetic.gof.factory.product.PepperPizza; import com.arithmetic.gof.factory.product.Pizza; /** * 简单的工厂/静态工厂 * * @author mazhiyuan * @date 2022/02/21 */ public class SimpleFactory { public static Pizza createPizza(String orderType) { Pizza pizza = null; System.out.println("使用简单工厂模式2"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希腊披萨 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 奶酪披萨 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披萨"); } return pizza; } }
工厂方法
特点: 将产品进行抽象 将工厂抽象 适用于多个工厂 多种具体的产品。产品只有一个抽象抽象产品披萨。
工厂方法和简单工厂区别:
- 简单工厂适用于 单个工厂, 工厂是一个具体的创建产品的工厂。
- 工厂方法, 本质是在简单工厂的基础上,把工厂的创建方法也进行了抽象为接口。 适用于多个工厂,这样在多个工厂进行调用的时候, 因为中间有一个抽象层,具体的调用不需要修改。 只需要扩展工厂种类和工厂对应的产品就可以。
缺点:分类等级多了内部需要if else进行分支判断
说明:
- 产品抽象 和 工厂抽象 属于抽象部分==框架
- 北京 和 伦敦工厂 以及 北京所有披萨 和 伦敦所有披萨 属于具体的子类实现部分。
产品实现
-
抽象产品代码
package com.arithmetic.gof.factoryMethod.product; /** * 披萨 * * @author mazhiyuan * @date 2022/02/22 */ public abstract class Pizza { /** * 产品名字 */ protected String name; /** * 披萨的味道 */ public abstract void pizzaTaste(); /** * 集名称 * * @param name 的名字 */ public void setName(String name) { this.name = name; } }
-
具体的产品-北京奶酪披散
package com.arithmetic.gof.factoryMethod.product; /** * bjcheese披萨 * * @author mazhiyuan * @date 2022/02/22 */ public class BJCheesePizza extends Pizza { /** * 披萨的味道 */ @Override public void pizzaTaste() { System.out.println("给制作北京奶酪披萨"); } }
-
具体的产品-北京胡椒披萨
package com.arithmetic.gof.factoryMethod.product; /** * bjpepper披萨 * * @author mazhiyuan * @date 2022/02/22 */ public class BJPepperPizza extends Pizza { /** * 披萨的味道 */ @Override public void pizzaTaste() { System.out.println("给制作北京胡椒披萨"); } }
-
具体的产品-伦敦奶酪披萨
package com.arithmetic.gof.factoryMethod.product; /** * ldcheese披萨 * * @author mazhiyuan * @date 2022/02/22 */ public class LDCheesePizza extends Pizza { /** * 披萨的味道 */ @Override public void pizzaTaste() { System.out.println("给制作伦敦奶酪披萨"); } }
-
具体的产品-伦敦胡椒披萨
package com.arithmetic.gof.factoryMethod.product; /** * ldpepper披萨 * * @author mazhiyuan * @date 2022/02/22 */ public class LDPepperPizza extends Pizza { /** * 披萨的味道 */ @Override public void pizzaTaste() { System.out.println("给制作伦敦胡椒披萨"); } }package com.arithmetic.gof.factoryMethod.product; /** * ldpepper披萨 * * @author mazhiyuan * @date 2022/02/22 */ public class LDPepperPizza extends Pizza { /** * 披萨的味道 */ @Override public void pizzaTaste() { System.out.println("给制作伦敦胡椒披萨"); } }
工厂实现
-
抽象工厂
package com.arithmetic.gof.factoryMethod.factory; import com.arithmetic.gof.factoryMethod.product.Pizza; /** * 工厂 * * @author mazhiyuan * @date 2022/02/22 */ public abstract class Factory { /** * 创建披萨 * * @param orderType 订单类型 * @return {@code Pizza} */ public abstract Pizza createPizza(String orderType); }
-
具体的工厂-北京工厂
package com.arithmetic.gof.factoryMethod.factory; import com.arithmetic.gof.factoryMethod.product.BJCheesePizza; import com.arithmetic.gof.factoryMethod.product.BJPepperPizza; import com.arithmetic.gof.factoryMethod.product.Pizza; /** * bjpizza工厂 * * @author mazhiyuan * @date 2022/02/22 */ public class BJPizzaFactory extends Factory{ /** * 创建披萨 * * @param orderType 订单类型 * @return {@code Pizza} */ @Override public Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } return pizza; } }
-
具体的工厂-伦敦工厂
package com.arithmetic.gof.factoryMethod.factory; import com.arithmetic.gof.factoryMethod.product.LDCheesePizza; import com.arithmetic.gof.factoryMethod.product.LDPepperPizza; import com.arithmetic.gof.factoryMethod.product.Pizza; /** * ldpizza工厂 * * @author mazhiyuan * @date 2022/02/22 */ public class LDPizzaFactory extends Factory{ /** * 创建披萨 * * @param orderType 订单类型 * @return {@code Pizza} */ @Override public Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new LDCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } }
工厂方法使用
package com.arithmetic.gof.factoryMethod;
import com.arithmetic.gof.factoryMethod.factory.BJPizzaFactory;
import com.arithmetic.gof.factoryMethod.factory.Factory;
import com.arithmetic.gof.factoryMethod.factory.LDPizzaFactory;
public class FactoryMethodMain {
public static void main(String[] args) {
Factory factory = new BJPizzaFactory();
factory.createPizza("cheese").pizzaTaste();
factory = new LDPizzaFactory();
factory.createPizza("cheese").pizzaTaste();
}
}
抽象工厂
特点: 抽象的工厂覆盖更广, 抽象的工厂可以创建多个抽象的产品,即多个类别的产品。
抽象工厂和工厂方法的区别:
- 工厂方法创建一类抽象产品(如以上实现披萨) , 抽象工厂可以创建多类产品, 多等级产品。
- 工厂方法内部只有抽象一个创建方法, 抽象工厂内部有多个抽象的创建方法
- 工厂方法适用于单一产品, 抽象工厂适用于复杂的产品, 系列产品, 产品簇。
- 抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品
抽象工厂的组成:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
参考:
产品实现
-
抽象产品1
interface Product1 { public void show(); }
-
具体产品1.1
class ConcreteProduct11 implements Product1 { public void show(){ } }
-
具体产品1.2
class ConcreteProduct12 implements Product1 { public void show(){ } }
-
抽象产品2
interface Product2 { public void show(); }
-
具体产品2.1
class ConcreteProduct21 implements Product2 { public void show(){ } }
-
具体产品2.2
class ConcreteProduct22 implements Product2 { public void show(){ } }
工厂实现
-
抽象工厂
interface AbstractFactory { public Product1 newProduct1(); public Product2 newProduct2(); }
-
具体工厂1
class ConcreteFactory1 implements AbstractFactory { public Product1 newProduct1() { System.out.println("具体工厂 1 生成-->具体产品 11..."); return new ConcreteProduct11(); } public Product2 newProduct2() { System.out.println("具体工厂 1 生成-->具体产品 21..."); return new ConcreteProduct21(); } }
-
具体工厂2
class ConcreteFactory2 implements AbstractFactory { public Product1 newProduct1() { System.out.println("具体工厂 2 生成-->具体产品 12..."); return new ConcreteProduct12(); } public Product2 newProduct2() { System.out.println("具体工厂 2 生成-->具体产品 22..."); return new ConcreteProduct22(); } }
-
使用
工厂设计模式总结
本质: 工厂设计模式本质是用来解决 产品创建的问题。 多种工厂类型的设计模式, 主要是围绕 单一产品 和 多种产品/多等级的产品问题进行的处理。多等级多种类的产品也可以使用简单工厂/工厂方法进行创建, 但是内部需要使用if else 进行判断。