设计模式——工厂模式

目录

  • 工厂模式
    • 需求
      • 传统方式
        • 类图
        • 优缺点
      • 使用简单工厂模式优化
    • 简单工厂模式
      • 基本介绍
      • 实例
    • 工厂方法模式
      • 介绍
      • 实例
    • 抽象工厂模式
      • 基本介绍
    • 小结

工厂模式

需求

一个披萨的项目:哟啊便于披萨种类的扩展,便于维护

  • 披萨的种类很多(比如 GreePizza CheesePizza等)
  • 披萨的制作有prepare(原料) bake(烘烤) cut(切割) box(打包)
  • 完成皮披萨的店的订购功能

传统方式

import java.util.Scanner;
/**
 * 这种方式存在问题
 * 如果新增一个类型的披萨,需要在OrderPizza类中修改代码
 * 也需要新增一个新类型的Pizza类
 * 这违反了OPC原则,即修改了使用方的代码(对扩展开放,对修改关闭)
 *
 * @author Han
 * @data 2023/10/28
 * @apiNode
 */
public class Test1 {
    public static void main(String[] args) {
        new OrderPizza();
    }
}

abstract class Pizza {
    private String name;

    public abstract void prepare();

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

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

    public void box() {
        System.out.println(name + " 打包 ");
    }

    public void setName(String name) {
        this.name = name;
    }
}

class OrderPizza {
    private Pizza pizza = null;

    public OrderPizza() {
        String type = this.getType();
        if ("greePizza".equals(type)) {
            pizza = new GreePizza();
            pizza.setName("greePizza");
        } else if ("cheesePizza".equals(type)) {
            pizza = new CheesePizza();
            pizza.setName("cheesePizza");
        } else {
            System.out.println("没有您这种披萨");
            return;
        }
        // 如果新增了新类型的披萨,需要修改这里的if else逻辑(修改使用方)
        pizza.bake();
        pizza.cut();
        pizza.box();
    }

    public String getType() {
        System.out.println("请输入要买的披萨类型");
        Scanner scna = new Scanner(System.in);
        String type = scna.nextLine();
        return type;
    }
}

// greePizza类型的披萨
class GreePizza extends Pizza {
    public GreePizza() {
        this.prepare();
    }

    @Override
    public void prepare() {
        System.out.println("准备greePizza原料");
    }
}

// cheesePizza类型的披萨
class CheesePizza extends Pizza {
    public CheesePizza() {
        this.prepare();
    }

    @Override
    public void prepare() {
        System.out.println("准备cheesePizza原料");
    }
}
// 如果需要新增新类型的披萨,要对提供方代码进行修改
类图

设计模式——工厂模式_第1张图片

优缺点
  • 优点是比较好理解,简单易操作
  • 缺点是违反了设计模式的ocp原则, 当我们给类增加新功能的时候,尽量不要修改代码,或者尽可能减少修改代码
  • 比如我们这时候要新增加一个Pizza的种类,我们需要对提供方修改,也要对使用方修改,违反了opc原则

使用简单工厂模式优化

  • 修改代码可以接收,但是如果在其他地方也有创建对象的代码,就意味着也要修改,而创建对象的代码,往往有多处
  • 思路:把创建对象封装到一个类中,这要我们有新的pizza种类时,只需要修改该类就可以,其他创建对象的代码就不需要修改了–> 简单工厂模式

简单工厂模式

基本介绍

  • 简单工厂模式是属于创建型模式,是工厂模式的一种,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式是工厂模式家族中最简单使用的模式
  • 简单工厂模式:定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
  • 在软件开发中,当我们会用到大量的创建某种类或某批对象是,就会使用到工厂模式

实例

package 工厂模式.简单工厂模式;

import java.util.Scanner;

// 造手机工厂
interface Phone {
    void call();
}

/**
 * 简单工厂模式,还是违反OCP原则
 *
 * @author Han
 * @data 2023/10/29
 * @apiNode
 */
public class SimpleFactory {
    public static void main(String[] args) {
        System.out.println("请输入手机品牌");
        String s = new Scanner(System.in).nextLine();
        PhoneFactory phoneFactory = new PhoneFactory();
        phoneFactory.createPhone(s).call();
    }
}

class MPhone implements Phone {

    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}

class IPhone implements Phone {

    @Override
    public void call() {
        System.out.println("苹果手机打电话");
    }
}

class PhoneFactory {
    public Phone createPhone(String name) {
        if ("小米手机".equals(name)) {
            return new MPhone();
        } else if ("苹果手机".equals(name)) {
            return new IPhone();
        } else {
            return null;
        }

    }
} 

工厂方法模式

介绍

工厂方法模式设计方案: 将创建对象的功能抽象成抽象方法,在不同的子类中具体实现

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

  • 工厂方法模式,创建一个工厂接口和创建多个工厂实现类,一旦需要增加新的功能,直接增加新的工厂类就可以了,不需要修改之前的代码。有利于代码的维护和扩展。

实例

package 工厂模式.简单工厂模式;

import java.util.Scanner;

// 手机抽象类
interface Phone1 {
    void call();
}

// 创建手机工厂
interface PhoneFactory1 {
    Phone1 create();
}

/**
 * @author Han
 * @data 2023/10/29
 * @apiNode
 */
public class MethodFactory {
    public static void main(String[] args) {
        new MPhoneFactory().create().call();
    }
}

// 小米手机工厂,实现手机工厂抽象类
class MPhoneFactory implements PhoneFactory1 {
    @Override
    public Phone1 create() {
        return new MPhone1();
    }
}

// 苹果手机工厂,实现手机工厂抽象类
class IPhoneFactory implements PhoneFactory1 {
    @Override
    public Phone1 create() {
        return new IPhone1();
    }
}

// 小米手机 实现手机类
class MPhone1 implements Phone1 {

    @Override
    public void call() {
        System.out.println("使用小米手机打电话");
    }
}

// 苹果手机,实现手机类
class IPhone1 implements Phone1 {

    @Override
    public void call() {
        System.out.println("使用苹果手机打电话");
    }
}

抽象工厂模式

基本介绍

  • 抽象工厂模式:定义了一个interface用来创建相关或有依赖关系的对象簇,而无需指明具体的类

  • 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合

  • 从设计层面上看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)

  • 将工厂抽象为两层,AbsFactory(抽象工厂)和 具体实现的工厂子类,我们可以根据创建对象类型使用对应的工厂子类,这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展

设计模式——工厂模式_第2张图片

  • 超级工厂

设计模式——工厂模式_第3张图片

  • 接口

设计模式——工厂模式_第4张图片

  • 下属工厂

设计模式——工厂模式_第5张图片

  • 产品

设计模式——工厂模式_第6张图片

设计模式——工厂模式_第7张图片

  • 测试类

设计模式——工厂模式_第8张图片

小结

  • 工厂模式的意义
    • 将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展性和维护性
  • 三种设计模式(简单工厂模式,工厂方法模式,抽象工厂模式)
  • 设计模式的依赖抽象原则
  • 创建对象实例时,不要直接new类,而是把这个new类的动作放在一个工厂的方法中,并返回,有的书上说,变量不要直接持有具体类的引用
  • 不要让类集成具体类,而是集成抽象类或者实现interface接口
  • 不要覆盖基类中已经实现的方法

你可能感兴趣的:(设计模式,设计模式,java,开发语言)