设计模式,工厂方法模式

工厂方法模式概述

工厂方法模式,是对简单工厂模式的进一步抽象和推广。以我个人理解,工厂方法模式就是对生产工厂的抽象,就是用一个生产工厂的工厂来进行目标对象的创建。

工厂方法模式的角色组成和简单工厂方法相比,创建了一个工厂的接口,生产相应的产品的工厂类都要实现此接口,然后多了一个用来创建对应工厂类对象的总工厂类,真正业务调用的就是这个总工厂类,这个总工厂类可以理解为用来创建工厂类的工厂类。

以上创建了一个工厂的接口,所有的用来生产目标产品的工厂都要实现这个接口,说明这是目标产品们不是只由一个工厂生产的,可能由多个工厂分开分别生产,即由多个简单工厂组成,为何要如此呢?见下文解释。

代码实现

为了更好的与简单工厂模式进行对比,直接引入简单工厂模式的博客的例子,见博客:

设计模式,简单工厂模式-CSDN博客

若这个餐馆的原先的那个厨师不会烹饪羊肉和牛肉,要新招一个会烹饪牛肉和羊肉的厨师。

工厂接口

两个厨师都要实现指定的工厂的接口,可以说他们都是生产菜品的工厂。

java 复制代码
public interface Factory {
    Cooking createCooking(String type);
}

厨师要实现对应的创造菜品的方法

工厂类

原先的工厂类:

java 复制代码
public class CookingFactory implements Factory {
    public Cooking createCooking(String type){
        Cooking cooking = null;
        switch (type){
            case "鱼":
                cooking = new CookingFish();
                break;
            case "土豆":
                cooking = new CookingPotato();
                break;
            case "鸡肉":
                cooking = new CookingChicken();
                break;
        }
        return cooking;
    }
}

原来的工厂类要做一些修改,让其实现工厂接口,并且那个生产菜品的方法不用设置为静态方法,因为这个方法不是直接由业务代码调用的,业务代码调用的是总工厂类的方法。

新的工厂类:

java 复制代码
public class CookingFactory2 implements Factory {

    public Cooking createCooking(String type){
        Cooking cooking = null;
        switch (type){
            case "羊肉":
                cooking = new CookingMutton();
                break;
            case "牛肉":
                cooking = new CookingBeef();
                break;
        }
        return cooking;
    }
}

新的工厂类和原来的工厂类的逻辑是一样的,只是所生产的菜品不一样。

java 复制代码
public class GetCooking {

    public static Cooking createFactory(String type) throws Exception {
        Factory factory = null;
        Cooking cooking = null;
        switch (type){
            case "鱼":
            case "土豆":
            case "鸡肉":
                factory = new CookingFactory();
                break;
            case "牛肉":
            case "羊肉":
                factory = new CookingFactory2();
                break;
            default:
                factory = null;
                break;
        }
        if (factory == null) {
            throw new Exception("菜品不存在");
        }
        cooking = factory.createCooking(type);
        return cooking;
    }
}

总工厂类

总工厂类有点像用来创建工厂类的工厂,最后将菜品的类型代入目标工厂类,获得目标菜品。

java 复制代码
public class GetCooking {

    public static Cooking createFactory(String type) throws Exception {
        Factory factory = null;
        Cooking cooking = null;
        switch (type){
            case "鱼":
            case "土豆":
            case "鸡肉":
                factory = new CookingFactory();
                break;
            case "牛肉":
            case "羊肉":
                factory = new CookingFactory2();
                break;
            default:
                factory = null;
                break;
        }
        if (factory == null) {
            throw new Exception("菜品不存在");
        }
        cooking = factory.createCooking(type);
        return cooking;
    }
}

总结

以上代码可以看出,这个模式的好处就是当要加一些新的产品时,不用去改动原先的工厂,而是直接创建一个新的工厂,更符合开闭原则。

可以看出,当一类产品只有一个工厂类时,就是简单工厂模式。当一类产品有多个工厂类时,就是工厂方法模式。工厂方法模式就是对简单工厂模式的进一步抽象和拓展。

但是这种模式还是有缺点,当增加了新的产品后,还是要对总工厂类中的代码进行一定修改,还是没有很好地符合开闭原则。当然后面还有更好的能解决此问题的模式,拭目以待吧。

相关推荐
Victor3561 小时前
Redis(25)Redis的RDB持久化的优点和缺点是什么?
后端
Victor3561 小时前
Redis(24)如何配置Redis的持久化?
后端
BD_Marathon6 小时前
【Flink】部署模式
java·数据库·flink
鼠鼠我捏,要死了捏8 小时前
深入解析Java NIO多路复用原理与性能优化实践指南
java·性能优化·nio
ningqw8 小时前
SpringBoot 常用跨域处理方案
java·后端·springboot
你的人类朋友8 小时前
vi编辑器命令常用操作整理(持续更新)
后端
superlls9 小时前
(Redis)主从哨兵模式与集群模式
java·开发语言·redis
胡gh9 小时前
简单又复杂,难道只能说一个有箭头一个没箭头?这种问题该怎么回答?
javascript·后端·面试
一只叫煤球的猫10 小时前
看到同事设计的表结构我人麻了!聊聊怎么更好去设计数据库表
后端·mysql·面试
uzong10 小时前
技术人如何对客做好沟通(上篇)
后端