设计模式——工厂模式(简单工厂、工厂方法、抽象工厂)

本文通过一个披萨订购系统的例子,详细介绍了简单工厂模式、工厂方法模式和抽象工厂模式的实现与应用场景。从最初的简单工厂模式解决代码耦合问题,到工厂方法模式应对不同地区口味的扩展,再到抽象工厂模式处理更多相关对象的创建,逐步展示了工厂模式在设计模式中的重要性和灵活性。
摘要由CSDN通过智能技术生成

1.1.简单工厂模式

  • 需求
    看一个披萨的项目:要便于披萨种类的扩展,要便于维护
    1. 披萨的种类很多(比如 GreekPizza、CheesePizza 等)
    2. 披萨的制作有 prepare,bake, cut, box
    3. 完成披萨店订购功能。
普通实现方法:

pizza抽象类:

/**
 * Description:pizza 两种pizza的抽象类
 *
 * @date : 2021-10-15
 **/
public abstract class Pizza {
    protected String name;

    //不同pizza 准备的材料不同,因此写为抽象方法
    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;
    }
}

希腊pizza:

public class GreekPizza extends Pizza{
    @Override
    public void prepare() {
        setName("希腊pizza");
        System.out.println("给希腊pizza准备材料~~");
    }
}

奶油pizza:

public class CheesePizza extends Pizza{

    @Override
    public void prepare() {
        setName("奶酪pizza");
        System.out.println("给奶油pizza准备材料~~");
    }
}

OrderPizza类,获取订单信息,根据订单制作pizza:

/**
 * Description:获取订单信息,根据订单制作pizza
 *
 * @date : 2021-10-15
 **/
public class OrderPizza {

    Scanner scanner = new Scanner(System.in);

    public OrderPizza(){
        Pizza pizza = null;
        String orderTpe;
        do{
            orderTpe = getType();
            if (orderTpe.equals("greek")){
                pizza = new GreekPizza();
            }else if (orderTpe.equals("cheek")){
                pizza = new CheesePizza();
            }else {
                break;
            }
            //制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }while (true);
    }

    private String getType() {
        System.out.println("请输入订购的pizza type(greek | cheek):");
        String s = scanner.nextLine();
        return s;
    }

}

客户端测试,完成pizza订购任务:

/**
 * Description:客户端,完成pizza订购任务
 *
 * @date : 2021-10-15
 **/
public class PizzaStore {

    public static void main(String[] args) {
        OrderPizza orderPizza = new OrderPizza();
    }

}

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yzugKdEK-1634630440035)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\1634284927943.png)]

传统的方式的优缺点:

改进的思路分析
分析:修改代码可以接受,但是如果我们在其它的地方也有创建Pizza的代码,就意味
着,也需要修改,而创建Pizza的代码,往往有多处。
思路:**把创建Pizza对象封装到一个类(工厂)**中,这样我们有新的Pizza种类时,只需要修改该
类就可,其它有创建到Pizza对象的代码就不需要修改了 -> 简单工厂模式

简单工厂模式代码示例:
/**
 * Description:
 *
 * @date : 2021-10-19
 **/
public class SimplePizzaFactory {

    public Pizza createPizza(String type) {
        System.out.println("使用简单工厂模式~~");
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("greek")) {
            pizza = new GreekPizza();
        }else
            throw new RuntimeException("参数有误");

        return pizza;
    }

}

1.2工厂方法模式:

新的需求
披萨项目新的需求:客户在点披萨时,可以点不同口味的披萨,比如 北京的奶酪pizza、
北京的胡椒pizza 或者是伦敦的奶酪pizza、伦敦的胡椒pizza。

**工厂方法模式设计方案:**将披萨项目的实例化功能抽象成抽象方法,在不同的口味点
餐子类中具体实现。
**工厂方法模式:**定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方
法模式将对象的实例化推迟到子类。

代码:

pizza:

public abstract class Pizza {
    protected String name;

    //不同pizza 准备的材料不同,因此写为抽象方法
    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;
    }
}

public class BJCheesePizza extends Pizza {

    @Override
    public void prepare() {
        setName("BJ的奶酪pizza");
        System.out.println("给BJ的奶油pizza准备材料~~");
    }
}

public class BJPaperPizza extends Pizza {
    @Override
    public void prepare() {
        setName("BJ的胡椒pizza");
        System.out.println("给BJ的胡椒pizza准备材料~~");
    }
}

public class LDCheesePizza extends Pizza {

    @Override
    public void prepare() {
        setName("LD的奶酪pizza");
        System.out.println("给LD的奶油pizza准备材料~~");
    }
}

public class LDPaperPizza extends Pizza {
    @Override
    public void prepare() {
        setName("LD的胡椒pizza");
        System.out.println("给LD的胡椒pizza准备材料~~");
    }
}

OrderPizza(工厂):

public abstract class OrderPizza {

    //定义抽象方法,创建pizza
    abstract Pizza createPizza(String orderTpe);

    Scanner scanner = new Scanner(System.in);

    public OrderPizza(){
        Pizza pizza = null;
        String orderTpe;//订购类型
        do{
            orderTpe = getType();
            pizza = createPizza(orderTpe);//由工厂子类实现
            //制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }while (true);
    }

    private String getType() {
        System.out.println("请输入订购的pizza type(cheese | paper):");
        String s = scanner.nextLine();
        return s;
    }

}

public class BJOrderPizza extends  OrderPizza{
	//子类实现创建pizza的抽象方法
    @Override
    Pizza createPizza(String orderTpe) {
        Pizza pizza = null;
        if (orderTpe.equals("cheese")){
            pizza = new BJCheesePizza();
        }else  if (orderTpe.equals("paper")){
            pizza = new BJPaperPizza();
        }

        return pizza;
    }
}

public class LDOrderPizza extends OrderPizza{
    //子类实现创建pizza的抽象方法
    @Override
    Pizza createPizza(String orderTpe) {
        Pizza pizza = null;
        if (orderTpe.equals("cheese")){
            pizza = new LDCheesePizza();
        }else  if (orderTpe.equals("paper")){
            pizza = new LDCheesePizza();
        }
        return pizza;
    }
}

PizzaStore:(客户端)

public class PizzaStore {

    public static void main(String[] args) {
        //根据不通的地区创建不同的工厂
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入您选择的地区(北京:BJ |伦敦:LD):");
        String loc = scanner.nextLine();
        if (loc.equals("BJ")){
            new BJOrderPizza();
        }else {
            new LDOrderPizza();
        }
    }

}

1.3抽象工厂模式

基本介绍

  1. 抽象工厂模式:定义了一个interface用于创建相关或有依赖关系的对象簇,而无需
    指明具体的类
  2. 抽象工厂模式可以将简单工厂模式和工厂方法模式进行整合。
  3. 从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)。
  4. 将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以
    根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,
    更利于代码的维护和扩展。
代码:
//一个抽象工厂模式的抽象层
public interface AbsFactory {
    //让下面的工厂子类具体实现
    Pizza createPizza(String type);
}

public class BJFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")){
            pizza = new BJCheesePizza();
        }else  if (type.equals("paper")){
            pizza = new BJPaperPizza();
        }

        return pizza;
    }
}

public class LDFactory implements AbsFactory{
    @Override
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")){
            pizza = new LDCheesePizza();
        }else  if (type.equals("paper")){
            pizza = new LDPaperPizza();
        }
        return pizza;
    }
}
public class OrderPizza {

    //聚合抽象工厂
    AbsFactory absFactory;

    Scanner scanner = new Scanner(System.in);

    public OrderPizza(AbsFactory absFactory){
        setFactory(absFactory);
    }


    private void setFactory(AbsFactory absFactory){
        Pizza pizza=null;
        String orderTpe;//订购类型
        do{
            orderTpe = getType();
            pizza = absFactory.createPizza(orderTpe);//由工厂子类实现
            //制作过程
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }while (true);
    }

    private String getType() {
        System.out.println("请输入订购的pizza type(cheese | paper):");
        String s = scanner.nextLine();
        return s;
    }

}

public class PizzaStore {

    public static void main(String[] args) {

        new OrderPizza(new BJFactory());
    }

}

工厂模式小结:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值