IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java设计模式——三种工厂模式 -> 正文阅读

[Java知识库]Java设计模式——三种工厂模式

一、简单工厂模式

1.1、基本介绍

  • 简单工厂模式是属于创建型模式,是工厂模式的一种。简单工厂模式是由一个简单工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单使用的模式。
  • 简单工厂模式:定义一个创建对象的类,由这个类来封装实例化对象的行为。
  • 使用场景:在软件开发中,当我们需要大量创建某种对象时,就会使用该模式。

1.2、举例演示

  • 例子:一家披萨店,现在推出奶酪披萨、胡椒披萨……。现在利用工厂模式做一个点餐系统。

1.3、案例需求分析

  • 我们假设每个披萨的制作流程都是一样的,即:原材料的准备(每一种披萨的原料不同)、烘烤、切割、打包。由于每种披萨的原料不同,所以需要将该类做成抽象类。然后让其他种类披萨去继承这个类。
  • 我们接着建造一个工厂,用来生产这个店里面所有种类的披萨。并且这个工厂要依赖所以种类的披萨。
  • 最后,我们让餐馆和这个工厂产生依赖,去进行点餐行为。

1.4、类图设计

在这里插入图片描述

1.5、代码展示

  • 首先,我们写出披萨的抽象类。
public abstract class Pizza {
    public String name;//披萨名称

    public abstract void prepare();

    public void back() {
        System.out.println(name + "开始烘烤");
    }

    public void cut() {
        System.out.println(name + "开始切割");
    }

    public void box() {
        System.out.println(name + "开始打包");
    }
}
  • 然后去实现各种类型的披萨。(为了方便,下面我将所有类型的披萨类写在一起,如果复制代码,需要注意,不要直接将所有复制在一个类里面);
//奶酪披萨
public class Cheese extends Pizza {
    public Cheese() {
        name = "奶酪披萨";
    }
    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}
//胡椒披萨
public class Pepper extends Pizza {
    public Pepper() {
        name = "胡椒披萨";
    }

    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}
  • 披萨准备好后,我们就需要建立工厂去生产。
public class Factory {
//通过接收输入的披萨种类,进行披萨的生产
    public Pizza creatPizza(String type) {
		Pizza pizza = null;
        if ("pepper".equals(type)) {
            pizza =  new Pepper();
        }else if ("cheese".equals(type)) {
            pizza = new Cheese();
        }

        return pizza;
    }
}
  • 最后,进行点餐
public class OrderPizza {

    public void order(Factory factory) {
        String type = null;
        Pizza pizza = null;

        do{
            type = getType();
            pizza = factory.creatPizza(type);
//如果返回null,说明这个工厂不能生产输入类型的披萨,或者该种类的披萨不存在。
            if (null == pizza) {
                System.out.println("没有该类型披萨");
                break;
            }

            pizza.prepare();
            pizza.back();
            pizza.cut();
            pizza.box();
        }while(true);
    }
//这个方法需要注意,他是用来获取输入披萨类型的,
    public String getType() {
        String type = null;

        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("输入披萨类型:");
            type = br.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return type;
    }
}
  • 最后,我们终于可以开始吃披萨了;
public class Test {
    public static void main(String[] args) {
        new OrderPizza().order(new Factory());
    }
}

二、工厂方法模式

2.1、基本介绍

  • 工厂方法模式:定义一个创建对象的的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类。

2.2、举例演示

  • 在上一个项目基础上添加新的需求。客户在点披萨时可以点不同地区口味的,比如北京的奶酪披萨、伦敦的奶酪披萨。都是奶酪披萨,但是不同地区口味不同。

2.3、案例分析

  • 有的人可能会说,这个用简单工厂模式不就可以解决了。但是,如果那样做,就会产生一个问题问题,类爆炸。想想全世界,要有多少种不同的披萨,那么,factory里面的条件判断要写多少条呀。想想都觉得可怕。这样会给后期软件的维护、可扩展性会带来问题。
  • 解决方案: 将披萨项目的实例化功能抽象成抽象方法,在不同的口味点餐子类中具体实现。

2.4、类图设计

在这里插入图片描述

2.5、代码展示

  • Pizza抽象类和上面一样,这里就不再写了。
  • 不同地区口味的披萨种类,
public class BJCheese extends Pizza {
    public BJCheese() {
        name = "北京奶酪披萨";
    }
    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}

public class BJPepper extends Pizza {
    public BJPepper() {
        name = "北京胡椒披萨";
    }

    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}

public class LDCheese extends Pizza {
    public LDCheese() {
        name = "伦敦奶酪披萨";
    }
    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}

public class LDPepper extends Pizza {
    public LDPepper() {
        name = "伦敦胡椒披萨";
    }

    @Override
    public void prepare() {
        System.out.println("开始准备" + name);
    }
}
  • 抽象工厂
public abstract class Factory {
    public abstract Pizza creatPizza(String type);

    public void order() {
        String type = null;
        Pizza pizza = null;
        while (true) {
            type = getType();
            pizza = creatPizza(type);

            if (null == pizza) {
                System.out.println("没有该类披萨");
                break;
            }
            pizza.prepare();
            pizza.back();
            pizza.cut();
            pizza.box();
        }
    }

    private String getType() {
        String type = null;

        try {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入披萨类型:");
            type = bf.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return type;
    }
}
  • 具体工厂
//北京的制作店铺
public class BJStory extends Factory {
    @Override
    public Pizza creatPizza(String type) {
        Pizza pizza = null;

        if ("cheese".equals(type)) {
            pizza = new BJCheese();
        }else if("pepper".equals(type)) {
            pizza = new BJPepper();
        }

        return pizza;
    }
}

//伦敦的制作店铺
public class LDStore extends Factory {
    @Override
    public Pizza creatPizza(String type) {
        Pizza pizza = null;
        if ("pepper".equals(type)) {
            pizza = new LDPepper();
        }else if ("cheese".equals(type)) {
            pizza = new LDCheese();
        }

        return pizza;
    }
  • 开始点餐。是不是主函数很简单,这就是使用设计模式的好处。
public class Test {
    public static void main(String[] args) {
        new BJStory().order();
    }
}

三、抽象工厂模式

3.1、基本介绍

  • 定义了一个interface用于创建相关或者依赖关系的对象簇,无需指明具体的类。
  • 从设计层面看,抽象工厂模式就是对简单工厂模式的更改
  • 将工厂抽象成两层,抽象工厂和具体实现的工厂子类,程序员可以根据创建对象类型使用对应的工厂子类。这样将单个工厂变成了工厂簇,更利于代码的维护和扩展。

3.2、举例演示

  • 和模式二例子一样,就不在书写了。

3.3、类图设计

在这里插入图片描述

3.4、代码展示

  • Pizza类、和其他口味的披萨类都和模式二相同,就不再写。
  • 工厂接口
public interface Factory {
    public Pizza creat(String type);
}
  • 具体工厂
public class BJFactory implements Factory {
    @Override
    public Pizza creat(String type) {
        Pizza pizza = null;

        if ("cheese".equals(type)) {
            pizza = new BJCheese();
        }else if ("pepper".equals(type)) {
            pizza = new BJPepper();
        }
        return pizza;
    }
}

public class LDFactory implements Factory {
    @Override
    public Pizza creat(String type) {
        Pizza pizza = null;

        if ("pepper".equals(type)) {
            pizza = new LDPepper();
        }else if ("cheese".equals(type)) {
            pizza = new LDCheese();
        }
        return pizza;
    }
}
  • 点餐类,另外一个LDOrder类和这个内容一样,就不再写了。或者还可以进行优化,将这些代码放进一个类里面,然后让具体的工厂再去继承,就可以节省大量的代码书写过程。
public class BJOrder {

    public void order(Factory factory) {
        String type = null;
        Pizza pizza = null;

        while (true) {
            type = getTYpe();
            pizza = factory.creat(type);

            if (null == pizza) {
                System.out.println("没有这类披萨");
                break;
            }

            pizza.prepare();
            pizza.back();
            pizza.cut();
            pizza.box();
        }
    }

    private String getTYpe() {
        String type = null;

        try {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("请输入披萨种类:");
            type = bf.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return type;
    }
}
  • 开始点餐
public class Store {
    public static void main(String[] args) {
        Factory factory = new BJFactory();

        new BJOrder().order(factory);
    }
}

四、小结

4.1、 工厂模式的意义

  • 将实例化对象的代码提起出来,放到一个类中统一进行管理和维护,达到和主项目的依赖关系解耦,从而提高项目的扩展和维护性。

4.2、设计模式的依赖抽象原则

  • 创建对象实例时,不要直接new类,而是把这个new类的功能放到一个工厂的方法中去,并返回。
  • 不要让类继承具体的类,而是继承抽象或者是实现接口。
  • 不要覆盖类中已经实现的方法。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:35:18  更:2022-02-07 13:35:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:25:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码