一文学透设计模式——工厂模式

工厂模式

概念

牛马人生公司最近开启了线上直播,直播中牛马人生公司宣称他们建造了一家世界上最为先进的工厂,任何人只要去到工厂面前,告诉工厂你要什么牌子的汽车,工厂就会给你一辆什么牌子的汽车。

这引起了粉丝朋友的注意,纷纷来到工厂一探究竟。

实现步骤

下面我们用代码来表示这个逻辑。

  1. 牛马人生公司重新定义了汽车的概念,他在幼儿园发出了100份的问卷调查,得到了汽车的定义,以及该拥有的功能。

    java 复制代码
    /**
     * 汽车的接口定义
     *
     * @author wanggt
     * @date 2023-06-17 20:45:27
     */
    public interface Car {
    
        /**
         * 往前走
         *
         * @author wanggt
         * @date 2023-06-17 20:46:21
         */
        void run();
    }
  2. 得到了汽车的最先进的概念之后,牛马人生公司开始设计一个拥有世界上最先进理念的工厂,一家可以制造任何汽车的工厂。在牛马人生公司的设想中,最开始支持的是五菱神车和小鹏汽车。

    java 复制代码
    /**
     * 汽车工厂类
     *
     * @author wanggt
     * @date 2023-06-17 20:51:13
     */
    public class CarFactory {
    
        /**
         * 在汽车工厂里根据汽车名称提车。
         *
         * @param name 汽车名称
         *
         * @author wanggt
         * @date 2023-06-17 21:00:09
         */
        public static Car getCar(String name) {
            if ("五菱".equals(name)) {
                return new WuLingCar();
            } else if ("小鹏".equals(name)) {
                return new XiaoPengCar();
            } else {
                return null;
            }
        }
    }
  3. 但是牛马人生公司并不知道汽车的制造方法,所以找到了小鹏和五菱的汽车厂商,学习了汽车的制造技术,以及授权。

    java 复制代码
    /**
     * 五菱神车
     *
     * @author wanggt
     * @date 2023-06-17 20:57:00
     */
    public class WuLingCar implements Car {
    
        @Override
        public void run() {
            System.out.println("五菱神车,送货载人都可以,我跑得飞快");
        }
    }
    java 复制代码
    /**
     * 小鹏汽车。
     *
     * @author wanggt
     * @date 2023-06-17 20:58:05
     */
    public class XiaoPengCar implements Car {
    
        @Override
        public void run() {
            System.out.println("小鹏汽车走啊走");
        }
    }
  4. 粉丝应邀而来,来到工厂前面,果然想要有啥车,工厂就会给啥车。只不过工厂的工程师说,目前工厂支持的车的类型还不多,后面会继续扩展的。

    java 复制代码
    public class SimpleFactoryDemo {
    
        public static void main(String[] args) {
            Car xiaoPengCar = CarFactory.getCar("小鹏");
            xiaoPengCar.run();
    
            System.out.println("===========");
    
            Car wuLingCar = CarFactory.getCar("五菱");
            wuLingCar.run();
        }
    }
    小鹏汽车走啊走
    ===========
    五菱神车,送货载人都可以,我跑得飞快
    

优缺点分析

我们来分析下牛马人生公司的这个工厂。其实他就是使用了简单工厂模式

优点是:减少了买一辆车的复杂性,我不需要知道汽车里面的构造是怎么样的,也不需要知道什么牌子的汽车就要到哪里去买车。顾客只需要告诉一个名字,这个工厂都可以给客户心目中的汽车。而且未来这个工厂还可以生产越来越多类型的汽车。

缺点呢,工厂的总工程师才不会告诉你,外表看起来光鲜亮丽的汽车工厂,里面是多么的杂乱。因为要制造的汽车类型太多了,每种汽车又有不同的配件。工厂已经不堪重负了。支持的汽车牌子越多,工厂里面就越混乱。

改进方案

日子一天天过去,汽车工厂兼容的汽车类型越来越多,工人们不得不连轴转。而且因为汽车工厂支持的汽车类型太多了,工厂里结构变得异常的复杂。而且性能也越来越低。

新招了一个设计师,刚进到工厂就辞职了。他说他就没有见过这么复杂的结构。

汽车工厂的总工程师想,这么下去可不行啊,全天下有多少汽车类型啊,要是都兼容了,那工厂估计吃不消啊。

于是,在总工程师薅掉了最后一根头发之后,想到了解决办法。

他可以使用工厂方法模式 来改造工厂。虽然也是工厂模式,但是工厂方法模式有效避免了修改现有的工厂。可以减少修改,而通过扩展的方式来达到目的。这就是所谓的开闭原则

总工程师得意地想,姜还是老的辣。

重新设计之后的汽车工厂如下所示:

  1. 汽车的概念还是一样的。

    java 复制代码
    /**
     * 汽车的接口定义
     *
     * @author wanggt
     * @date 2023-06-17 20:45:27
     */
    public interface Car {
    
        /**
         * 往前走
         *
         * @author wanggt
         * @date 2023-06-17 20:46:21
         */
        void run();
    }
  2. 总工程师增加了一个汽车工厂的设计规范。这里就是跟之前不同的地方。

    java 复制代码
    /**
     * 汽车工厂类的接口定义。
     *
     * @author wanggt
     * @date 2023-06-17 20:51:13
     */
    public interface CarFactory {
    
        /**
         * 在汽车工厂里根据汽车名称提车。
         *
         * @author wanggt
         * @date 2023-06-17 21:00:09
         */
        Car getCar();
    }
  3. 根据汽车的设计规范,打造了一个专门生产五菱神车的工厂。

    java 复制代码
    /**
     * 汽车工厂类
     *
     * @author wanggt
     * @date 2023-06-17 20:51:13
     */
    public class WuLingCarFactory implements CarFactory {
    
        /**
         * 在汽车工厂里根据汽车名称提车。
         *
         * @author wanggt
         * @date 2023-06-17 21:00:09
         */
        @Override
        public Car getCar() {
            return new WuLingCar();
        }
    }
    java 复制代码
    /**
     * 五菱神车
     *
     * @author wanggt
     * @date 2023-06-17 20:57:00
     */
    public class WuLingCar implements Car {
    
        @Override
        public void run() {
            System.out.println("五菱神车,送货载人都可以,我跑得飞快");
        }
    }
  4. 同样,又打造了一个小鹏汽车的工厂。

    java 复制代码
    /**
     * 汽车工厂类
     *
     * @author wanggt
     * @date 2023-06-17 20:51:13
     */
    public class XiaoPengCarFactory implements CarFactory {
    
        /**
         * 在汽车工厂里根据汽车名称提车。
         *
         * @author wanggt
         * @date 2023-06-17 21:00:09
         */
        @Override
        public Car getCar() {
            return new XiaoPengCar();
        }
    }
    java 复制代码
    /**
     * 小鹏汽车。
     *
     * @author wanggt
     * @date 2023-06-17 20:58:05
     */
    public class XiaoPengCar implements Car {
    
        @Override
        public void run() {
            System.out.println("小鹏汽车走啊走");
        }
    }
  5. 粉丝听闻汽车工厂大改造,又来到汽车工厂来围观。发现了汽车工厂的似乎比以前要复杂了,还需要知道小鹏汽车工厂,五菱汽车工厂。纷纷有些不满,但总算还在意料之内。

    java 复制代码
    public class FactoryMethodDemo {
    
        public static void main(String[] args) {
            XiaoPengCarFactory xiaoPengCarFactory = new XiaoPengCarFactory();
            Car xiaoPengCar = xiaoPengCarFactory.getCar();
            xiaoPengCar.run();
    
            System.out.println("===========");
            WuLingCarFactory wuLingCarFactory = new WuLingCarFactory();
            Car wuLingCar = wuLingCarFactory.getCar();
            wuLingCar.run();
        }
    }
  6. 总工程师松了一口气,以后总算不用担心兼容新的汽车了。只要新建一个对应的工厂就可以生产新的汽车了。

可以看出来,简单工厂模式胜在简单,一个工厂类,一个静态方法就可以获取各种对象。工厂方法模式扩展性比较强,而且满足开闭原则。

选择使用哪一个,主要是看简单不简单。

相关推荐
喵叔哟9 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生15 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
闲人一枚(学习中)22 分钟前
设计模式-创建型-抽象工厂模式
设计模式·抽象工厂模式
不是二师兄的八戒38 分钟前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php
爱编程的小生1 小时前
Easyexcel(2-文件读取)
java·excel
带多刺的玫瑰1 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
计算机毕设指导62 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
Gu Gu Study2 小时前
枚举与lambda表达式,枚举实现单例模式为什么是安全的,lambda表达式与函数式接口的小九九~
java·开发语言
Chris _data2 小时前
二叉树oj题解析
java·数据结构
牙牙7052 小时前
Centos7安装Jenkins脚本一键部署
java·servlet·jenkins