当前位置: 首页 > article >正文

第五章 工厂模式

文章目录

  • 一、简单工厂模式
    • 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{
    @Override
    public void prepare() {
        System.out.println("准备胡椒披萨的原材料");
    }
}

子类印度披萨 GreekPizza

package tanchishell.SJMS.factory;

public class GreekPizza extends Pizza{
    @Override
    public 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{
    @Override
    public void prepare() {
        System.out.println("准备希腊披萨的原材料");
    }
}

胡椒披萨

package tanchishell.SJMS.factory;

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

中国披萨

package tanchishell.SJMS.factory;

public class ChinesePizza extends Pizza {
    @Override
    public 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);

            //输出 pizza
            if(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{
    @Override
    public 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{
    @Override
    public void prepare() {
        setName("北京奶酪披萨");
        System.out.println("准备北京制作奶酪披萨");
    }
}

北京胡椒披萨 BJPepperPizza

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

伦敦奶酪披萨 LDCheesePizza

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

伦敦胡椒披萨 LDPepperPizza

public class LDPepperPizza extends Pizza {
    @Override
    public 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{
    @Override
    Pizza 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{
    @Override
    Pizza 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 stub
        return 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{
    @Override
    public 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{
    @Override
    public 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) { // 订购 ok
                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 类型: ---- 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开始,所以取月份要+1
        System.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();

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

工厂模式小结

在这里插入图片描述


http://www.kler.cn/a/14143.html

相关文章:

  • [Python] if __name__ == ‘__main__‘的作用
  • 力扣 1493(删掉一个元素以后全为 1 的最长子数组)Java
  • NAT转换
  • Mysql——》范式
  • Android 10 设置人脸解锁时,锁屏显示人脸解锁图标
  • 《用于估计血压变化的光电体积描记图和心电图的特征》阅读笔记
  • 设计模式--原型模式
  • 海光信息业绩高歌猛进,但其作为国产CPU龙头的“地基”并不牢固
  • IPSec数据报文封装格式详解
  • 2023常用的10款电力电子系统仿真分析软件推荐
  • CCED,落下帷幕,国产新型编辑技术的锋芒,终于露出来了
  • [ES6]函数
  • 2023 年嵌入式世界的3 大趋势分析
  • API简介(一)
  • 菜鸟教程,前端部分测验
  • mysql的读提交与可重复读
  • 【Python】原来处理大文件也可以这么简单?
  • 程序员应该具备哪些良好的编程习惯?
  • EL 表达式--各种运算-代码演示--EL 的 11 个隐含对象--pageContext 对象介绍--JSTL 标签库介绍--core 核心库--综合代码
  • Python Selenium 关键字驱动