> 文章列表 > 第五章 工厂模式

第五章 工厂模式

第五章 工厂模式

文章目录

  • 一、简单工厂模式
    • 1、传统方式实现披萨订购( 可以忽略)
      • 披萨父类 Pizza
      • 子类胡椒披萨 PepperPizza
      • 子类印度披萨 GreekPizza
      • 订购披萨 OrderPizza
      • 订购披萨的 客户端 PizzaStore
      • 运行结果
      • 传统的方式的优缺点,新增子类需要修改的地方牵扯太多
      • 传统方式的究极耦合
    • 2、使用简单工厂模式 🔞🔞🔞
    • 完整代码
      • 披萨父类 Pizza
      • 披萨子类 GreekPizza / PepperPizza / ChinesePizza
      • 订购披萨 OrderPizza
      • 披萨简单工厂 SimpleFactory
      • 客户端订购披萨 PizzaStore
      • 添加披萨子类 USAPizza 美国披萨
      • 运行结果
  • 二、工厂方法模式
    • 完整代码
      • 披萨父类 Pizza
      • 北京奶酪披萨 BJCheesePizza
      • 北京胡椒披萨 BJPepperPizza
      • 伦敦奶酪披萨 LDCheesePizza
      • 伦敦胡椒披萨 LDPepperPizza
      • 抽象订购披萨 OrderPizza (充当工厂角色)
    • 订购披萨子类 BJOrderPizza / LDOrderPizza
      • BJOrderPizza
      • LDOrderPizza
      • 客户端订购披萨
    • 运行结果
      • 添加披萨口味
  • 三、抽象工厂模式
    • 代码示例
    • 抽象工厂 AbsFactory 接口
    • 北京披萨工厂 BJFactory 实现 AbsFactory 接口
    • 伦敦披萨工厂 LDFactory 实现 AbsFactory 接口
    • 披萨订购 OrderPizza 聚合 AbsFactory 接口
    • 客户端订购披萨
    • 运行结果
  • JDKの工厂模式: Calendar日历类
  • 工厂模式小结


一、简单工厂模式

第五章 工厂模式

1、传统方式实现披萨订购( 可以忽略)

第五章 工厂模式

披萨父类 Pizza

package tanchishell.SJMS.factory;//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {protected String name;//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现public abstract void prepare();//一下流程是各种披萨共有的,子类继承后自动实现public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;}
}

子类胡椒披萨 PepperPizza

package tanchishell.SJMS.factory;public class PepperPizza extends Pizza{@Overridepublic void prepare() {System.out.println("准备胡椒披萨的原材料");}
}

子类印度披萨 GreekPizza

package tanchishell.SJMS.factory;public class GreekPizza extends Pizza{@Overridepublic void prepare() {System.out.println("准备希腊披萨的原材料");}
}

订购披萨 OrderPizza

package tanchishell.SJMS.factory;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class OrderPizza {//构造器public OrderPizza() {Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");} else {System.out.println("请检查您的输入");break;}//输出 pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}//获取披萨的类型private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 类型:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}

订购披萨的 客户端 PizzaStore

package tanchishell.SJMS.factory;//订购Pizza的客户端
public class PizzaStore {public static void main(String[] args) {new OrderPizza();}}

运行结果

第五章 工厂模式

传统的方式的优缺点,新增子类需要修改的地方牵扯太多

第五章 工厂模式

第五章 工厂模式
第五章 工厂模式

传统方式的究极耦合

新增一个子类,所有的OrderPizza类都需要修改,一旦过多,耦合度极高。

第五章 工厂模式

2、使用简单工厂模式 🔞🔞🔞

第五章 工厂模式

第五章 工厂模式
第五章 工厂模式
第五章 工厂模式

完整代码

披萨父类 Pizza

package tanchishell.SJMS.factory;//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {protected String name;//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现public abstract void prepare();//以下流程是各种披萨共有的,子类继承后自动实现public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;}
}

披萨子类 GreekPizza / PepperPizza / ChinesePizza

印度披萨

package tanchishell.SJMS.factory;public class GreekPizza extends Pizza{@Overridepublic void prepare() {System.out.println("准备希腊披萨的原材料");}
}

胡椒披萨

package tanchishell.SJMS.factory;public class PepperPizza extends Pizza{@Overridepublic void prepare() {System.out.println("准备胡椒披萨的原材料");}
}

中国披萨

package tanchishell.SJMS.factory;public class ChinesePizza extends Pizza {@Overridepublic void prepare() {System.out.println("准备中国披萨的原材料");}
}

订购披萨 OrderPizza

package tanchishell.SJMS.factory;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class OrderPizza{//定义一个简单工厂对象
//    SimpleFactory simpleFactory = new SimpleFactory(); //如果OrderPizza 和 工厂类同生共死就是组合关系SimpleFactory simpleFactory;Pizza pizza = null;//构造器public OrderPizza(SimpleFactory simpleFactory) {setFactory(simpleFactory);}public void setFactory(SimpleFactory simpleFactory) {String orderType = ""; //用户输入的,先定义一个空串提供下面使用this.simpleFactory = simpleFactory; //设置简单工厂对象do {orderType = getType();//可以在这里更换工厂方法pizza = this.simpleFactory.createPizza(orderType);//输出 pizzaif(pizza != null) { //订购成功pizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println(" 订购披萨失败 ");break;}}while(true);}//获取用户需要披萨的类型private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 类型:");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}

披萨简单工厂 SimpleFactory

package tanchishell.SJMS.factory;/*** 添加新品种的 披萨 只需要添加一个Pizza子类和在工厂类中做一个判断*/public class SimpleFactory {//更加 orderType 返回对应的 Pizza 对象public Pizza createPizza(String orderType) {Pizza pizza = null;System.out.println("使用简单工厂模式");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("chinese")) {pizza = new ChinesePizza();pizza.setName(" 中国披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}else if (orderType.equals("usa")){  //新增美国披萨pizza = new USAPizza();pizza.setName("我是美国披萨");}return pizza;}//简单工厂模式 也叫 静态工厂模public static Pizza createPizza2(String orderType) {Pizza pizza = null;System.out.println("使用简单工厂模式 2");if (orderType.equals("greek")) {pizza = new GreekPizza();pizza.setName(" 希腊披萨 ");} else if (orderType.equals("chinese")) {pizza = new ChinesePizza();pizza.setName(" 中国披萨 ");} else if (orderType.equals("pepper")) {pizza = new PepperPizza();pizza.setName("胡椒披萨");}return pizza;}
}

客户端订购披萨 PizzaStore

package tanchishell.SJMS.factory;//订购Pizza的客户端
public  class PizzaStore {public static void main(String[] args) {
//        new OrderPizza();//获取订单,传入一个工厂new OrderPizza(new SimpleFactory());System.out.println("退出程序");}}

添加披萨子类 USAPizza 美国披萨

package tanchishell.SJMS.factory;public class USAPizza extends Pizza{@Overridepublic void prepare() {System.out.println("准备制作美国披萨");}
}

第五章 工厂模式

运行结果

第五章 工厂模式

二、工厂方法模式

第五章 工厂模式
第五章 工厂模式
第五章 工厂模式

完整代码

披萨父类 Pizza

package tanchishell.SJMS.methedfactory;//抽象类 Pizza 后续的所有 披萨都继承该类
public abstract class Pizza {protected String name;//由于不同的披萨有着不同的原材料所有 准备原材料的方法是抽象的需要子类自己去实现public abstract void prepare();//以下流程是各种披萨共有的,子类继承后自动实现public void bake() {System.out.println(name + " baking;");}public void cut() {System.out.println(name + " cutting;");}public void box() {System.out.println(name + " boxing;");}public void setName(String name) {this.name = name;}
}

北京奶酪披萨 BJCheesePizza

public class BJCheesePizza extends Pizza{@Overridepublic void prepare() {setName("北京奶酪披萨");System.out.println("准备北京制作奶酪披萨");}
}

北京胡椒披萨 BJPepperPizza

public class BJPepperPizza extends Pizza {@Overridepublic void prepare() {setName("北京胡椒披萨");System.out.println("准备北京胡椒披萨的原材料");}
}

伦敦奶酪披萨 LDCheesePizza

public class LDCheesePizza extends Pizza{@Overridepublic void prepare() {setName("伦敦奶酪披萨");System.out.println("准备伦敦制作奶酪披萨");}
}

伦敦胡椒披萨 LDPepperPizza

public class LDPepperPizza extends Pizza {@Overridepublic void prepare() {setName("伦敦胡椒披萨");System.out.println("准备伦敦胡椒披萨的原材料");}
}

抽象订购披萨 OrderPizza (充当工厂角色)

package tanchishell.SJMS.methedfactory;import tanchishell.SJMS.factory.SimpleFactory;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public abstract class OrderPizza {//定义一个抽象方法,createPizza , 让各个工厂子类自己实现abstract Pizza createPizza(String orderType);// 构造器public OrderPizza() {Pizza pizza = null;String orderType; // 订购披萨的类型do {orderType = getType();pizza = createPizza(orderType); //抽象方法,由工厂子类完成//输出 pizza 制作过程pizza.prepare();pizza.bake();pizza.cut();pizza.box();} while (true);}//获取用户需要披萨的类型private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 类型: ---- pepper(胡椒口味) -----cheese(奶酪口味)");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}}

订购披萨子类 BJOrderPizza / LDOrderPizza

BJOrderPizza

package tanchishell.SJMS.methedfactory;public class BJOrderPizza extends OrderPizza{@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")) {pizza = new BJPepperPizza();}/*** 需要添加北京口味的披萨只需要设计一个披萨子类 并在 这里加一个判断*/return pizza;}
}

LDOrderPizza

package tanchishell.SJMS.methedfactory;public class LDOrderPizza extends OrderPizza{@OverridePizza createPizza(String orderType) {Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}
// TODO Auto-generated method stubreturn pizza;}
}

客户端订购披萨

package tanchishell.SJMS.methedfactory;import java.util.Scanner;public class PizzaStore {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请选择您的口味---目前支持 1,北京口味 ----2,伦敦口味");int i = scanner.nextInt();if(i == 1){new BJOrderPizza();}if(i == 2){new LDOrderPizza();}}
}

运行结果

第五章 工厂模式

添加披萨口味

新增子类实现

第五章 工厂模式

在对应的 Order 实现类进行判断

第五章 工厂模式

测试

第五章 工厂模式

第五章 工厂模式

三、抽象工厂模式

第五章 工厂模式

第五章 工厂模式

抽象工厂模式是对简单工厂和工厂方法的一个整合

代码示例

pizza 代码和 工厂方法模式一致,就不写了

抽象工厂 AbsFactory 接口

public interface AbsFactory {//让下面的工厂子类来 具体实现Pizza createPizza(String orderType);
}

北京披萨工厂 BJFactory 实现 AbsFactory 接口

package tanchishell.SJMS.absFactory;public class BJFactory implements AbsFactory{@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工厂模式~");Pizza pizza = null;if(orderType.equals("cheese")) {pizza = new BJCheesePizza();} else if (orderType.equals("pepper")){pizza = new BJPepperPizza();}/*** 添加披萨子类和判断就能完成披萨口味的添加*/return pizza;}
}

伦敦披萨工厂 LDFactory 实现 AbsFactory 接口

package tanchishell.SJMS.absFactory;public class LDFactory implements AbsFactory{@Overridepublic Pizza createPizza(String orderType) {System.out.println("~使用的是抽象工厂模式~");Pizza pizza = null;if (orderType.equals("cheese")) {pizza = new LDCheesePizza();} else if (orderType.equals("pepper")) {pizza = new LDPepperPizza();}return pizza;}
}

披萨订购 OrderPizza 聚合 AbsFactory 接口

package tanchishell.SJMS.absFactory;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class OrderPizza {AbsFactory factory;// 构造器public OrderPizza(AbsFactory factory) {setFactory(factory);}private void setFactory(AbsFactory factory) {Pizza pizza = null;String orderType = ""; // 用户输入this.factory = factory;do {orderType = getType();
// factory 可能是北京的工厂子类,也可能是伦敦的工厂子类pizza = factory.createPizza(orderType);if (pizza != null) { // 订购 okpizza.prepare();pizza.bake();pizza.cut();pizza.box();} else {System.out.println("订购失败");break;}} while (true);}// 写一个方法,可以获取客户希望订购的披萨种类private String getType() {try {BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));System.out.println("input pizza 类型: ---- pepper(胡椒口味) -----cheese(奶酪口味)");String str = strin.readLine();return str;} catch (IOException e) {e.printStackTrace();return "";}}
}

客户端订购披萨

package tanchishell.SJMS.absFactory;import java.util.Scanner;public class PizzaStore {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("请选择您的口味---目前支持 1,北京口味 ----2,伦敦口味");int i = scanner.nextInt();if(i == 1){new OrderPizza(new BJFactory());}if(i == 2){new OrderPizza(new LDFactory());}}
}

运行结果

第五章 工厂模式

JDKの工厂模式: Calendar日历类

第五章 工厂模式

        Calendar cal = Calendar.getInstance();
// 注意月份下标从0开始,所以取月份要+1System.out.println("年:" + cal.get(Calendar.YEAR));System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));System.out.println("分:" + cal.get(Calendar.MINUTE));System.out.println("秒:" + cal.get(Calendar.SECOND));

进入Calendar cal = Calendar.getInstance();

第五章 工厂模式
第五章 工厂模式
第五章 工厂模式

工厂模式小结

第五章 工厂模式