• 工厂方法模式-原理解析-逐步构建-java实战


    Why?

    为什么我们可以用简单粗暴的方式来完成产品经理给的需求,还要用 23种设计模式 中的工厂方法模式来重构代码呢?

    这个问题在我刚入行的时候是不懂的,理解需求,完成代码,前后端联调,提交测试,业务上线一气呵成。

    当我们的需求需要兼容多系统、多任务、多规则的时候,用简单的 CRUD 来完成就会让代码变的很臃肿、耦合、不优雅。那么如何写出优雅的代码呢?今天我来用工厂方法模式一步一步带你去重构代码,让代码变得优雅起来

    业务场景

    需求一

    丰收村的苹果到了成熟的季节,需要采摘、包装、加工、运输这几个环节,需要我们来实现一下业务代码

    代码实现

    苹果类
    public class Apple {
        public void pick() {
            System.out.println("采摘苹果...");
        }
    
        public void pack() {
            System.out.println("包装苹果...");
        }
    
        public void process() {
            System.out.println("加工苹果...");
        }
    
        public void transport() {
            System.out.println("运输苹果....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    Main 方法
    public class Main {
    
        public static void main(String[] args) {
            Apple apple = new Apple();
            apple.pick();
            apple.pack();
            apple.process();
            apple.transport();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    output
    采摘苹果...
    包装苹果...
    加工苹果...
    运输苹果....
    
    • 1
    • 2
    • 3
    • 4
    思路

    我们大部分的需求都是这种简单的 CRUD,无脑写就完事了。

    需求二

    丰收村除了苹果到了成熟的季节,梨也成熟了,现在需要我们来完成这两个产品的采摘、包装、加工、运输这几个环节,需要我们来实现一下业务代码

    代码实现

    水果基类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/16:11
     * @Description: 抽象出操作环节抽象接口让每个农产品去继承即可
     */
    public abstract class Fruit {
    
        /**
         * 采摘
         */
        public abstract void pick();
    
        /**
         * 包装
         */
        public abstract void pack();
    
        /**
         * 加工
         */
        public abstract void process();
    
        /**
         * 运输
         */
        public abstract void transport();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    苹果实现类
    public class Apple extends Fruit{
        @Override
        public void pick() {
            System.out.println("采摘苹果...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装苹果...");
        }
    
        @Override
        public void process() {
            System.out.println("加工苹果...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输苹果....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    梨子实现类
    public class Pear extends Fruit{
        @Override
        public void pick() {
            System.out.println("采摘梨...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装梨...");
        }
    
        @Override
        public void process() {
            System.out.println("加工梨...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输梨....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    水果工厂基类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/16:39
     * @Description: 水果工厂基类
     */
    public interface FruitFactory {
    
        /**
         * 采摘
         */
        Fruit pick();
    
        /**
         * 包装
         */
        Fruit pack();
    
        /**
         * 加工
         */
        Fruit process();
    
        /**
         * 运输
         */
        Fruit transport();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    苹果工厂类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/16:41
     * @Description:苹果工厂类
     */
    public class AppleFactory implements FruitFactory{
    
        @Override
        public Fruit pick() {
            return  new Apple();
        }
    
        @Override
        public Fruit pack() {
            return  new Apple();
        }
    
        @Override
        public Fruit process() {
            return new Apple();
        }
    
        @Override
        public Fruit transport() {
            return  new Apple();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    梨子工厂类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/16:41
     * @Description: 梨子工厂类
     */
    public class PearFactory implements FruitFactory{
    
        @Override
        public Fruit pick() {
            return new Pear();
        }
    
        @Override
        public Fruit pack() {
            return new Pear();
        }
    
        @Override
        public Fruit process() {
            return new Pear();
        }
    
        @Override
        public Fruit transport() {
            return new Pear();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    业务消费类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/16:49
     * @Description: 业务消费类
     */
    public class Bussiness {
    
        public static void pick(FruitFactory fruitFactory) {
            fruitFactory.pick().pick();
        }
    
        public static void pack(FruitFactory fruitFactory) {
            fruitFactory.pack().pack();
        }
    
        public static void process(FruitFactory fruitFactory) {
            fruitFactory.process().process();
        }
    
        public static void transport(FruitFactory fruitFactory) {
            fruitFactory.transport().transport();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    Main测试类
    public class Main {
    
        public static void main(String[] args) {
            Bussiness.pick(new AppleFactory());
            Bussiness.pack(new AppleFactory());
            Bussiness.process(new AppleFactory());
            Bussiness.transport(new AppleFactory());
            System.out.println("============");
            Bussiness.pick(new PearFactory());
            Bussiness.pack(new PearFactory());
            Bussiness.process(new PearFactory());
            Bussiness.transport(new PearFactory());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    output
    采摘苹果...
    包装苹果...
    加工苹果...
    运输苹果....
    ============
    采摘梨...
    包装梨...
    加工梨...
    运输梨....
    
    进程已结束,退出代码0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    思路

    采用水果工厂类(FruitFactory)定义顶层操作接口,每个产品(AppleFactory、PearFactory)去实现水果工厂类,调用时仅需要调用业务静态类(Bussiness)对应方法既可

    需求三

    幸福村看到丰收村的农产品大卖,他们也想把自己村的蔬菜产业进行销售,现在需要我们在已有的系统中加入蔬菜销售的逻辑

    代码实现

    农产品基类
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/17:06
     * @Description: 农产品基类,定义相关操作
     */
    public abstract class FarmProduct {
    
        /**
         * 采摘
         */
        public abstract void pick();
    
        /**
         * 包装
         */
        public abstract void pack();
    
        /**
         * 加工
         */
        public abstract void process();
    
        /**
         * 运输
         */
        public abstract void transport();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    相应农产品继承农产品基类
    public class Apple extends FarmProduct {
        @Override
        public void pick() {
            System.out.println("采摘苹果...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装苹果...");
        }
    
        @Override
        public void process() {
            System.out.println("加工苹果...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输苹果....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class Pear extends FarmProduct {
        @Override
        public void pick() {
            System.out.println("采摘梨...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装梨...");
        }
    
        @Override
        public void process() {
            System.out.println("加工梨...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输梨....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class Cabbage extends FarmProduct {
        @Override
        public void pick() {
            System.out.println("采摘卷心菜...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装卷心菜...");
        }
    
        @Override
        public void process() {
            System.out.println("加工卷心菜...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输卷心菜....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class Celery extends FarmProduct {
        @Override
        public void pick() {
            System.out.println("采摘芹菜...");
        }
    
        @Override
        public void pack() {
            System.out.println("包装芹菜...");
        }
    
        @Override
        public void process() {
            System.out.println("加工芹菜...");
        }
    
        @Override
        public void transport() {
            System.out.println("运输芹菜....");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    农产品抽象工厂
    /**
     * @Author: Lisy
     * @Date: 2022/10/19/17:06
     * @Description: 农产品抽象工厂
     */
    public abstract class AbstractFarmProduct {
    
    
        /**
         * 采摘
         */
        public abstract FarmProduct pick();
    
        /**
         * 包装
         */
        public abstract FarmProduct pack();
    
        /**
         * 加工
         */
        public abstract FarmProduct process();
    
        /**
         * 运输
         */
        public abstract FarmProduct transport();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    苹果工厂类
    public class AppleFactory extends AbstractFarmProduct {
    
        @Override
        public FarmProduct pick() {
            return new Apple();
        }
    
        @Override
        public FarmProduct pack() {
            return new Apple();
        }
    
        @Override
        public FarmProduct process() {
            return new Apple();
        }
    
        @Override
        public FarmProduct transport() {
            return new Apple();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    梨子工厂类
    public class PearFactory extends AbstractFarmProduct {
    
        @Override
        public FarmProduct pick() {
            return new Pear();
        }
    
        @Override
        public FarmProduct pack() {
            return new Pear();
        }
    
        @Override
        public FarmProduct process() {
            return new Pear();
        }
    
        @Override
        public FarmProduct transport() {
            return new Pear();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    芹菜工厂类
    public class CeleryFactory extends AbstractFarmProduct {
    
        @Override
        public FarmProduct pick() {
            return new Celery();
        }
    
        @Override
        public FarmProduct pack() {
            return new Celery();
        }
    
        @Override
        public FarmProduct process() {
            return new Celery();
        }
    
        @Override
        public FarmProduct transport() {
            return new Celery();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    卷子菜工厂类
    public class CabbageFactory extends AbstractFarmProduct {
    
        @Override
        public FarmProduct pick() {
            return new Cabbage();
        }
    
        @Override
        public FarmProduct pack() {
            return new Cabbage();
        }
    
        @Override
        public FarmProduct process() {
            return new Cabbage();
        }
    
        @Override
        public FarmProduct transport() {
            return new Cabbage();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    业务消费类
    public class Bussiness {
    
        public static void pick(AbstractFarmProduct abstractFarmProduct) {
            abstractFarmProduct.pick().pick();
        }
    
        public static void pack(AbstractFarmProduct abstractFarmProduct) {
            abstractFarmProduct.pack().pack();
        }
    
        public static void process(AbstractFarmProduct abstractFarmProduct) {
            abstractFarmProduct.process().process();
        }
    
        public static void transport(AbstractFarmProduct abstractFarmProduct) {
            abstractFarmProduct.transport().transport();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    Main 测试类
    public class Main {
    
        public static void main(String[] args) {
            Bussiness.pick(new CabbageFactory());
            System.out.println("=========");
            Bussiness.pick(new AppleFactory());
            System.out.println("=========");
            Bussiness.pack(new AppleFactory());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    output
    采摘卷心菜...
    =========
    采摘苹果...
    =========
    包装苹果...
    
    • 1
    • 2
    • 3
    • 4
    • 5

    思路

    通过抽象出一个公共抽象基类(FarmProduct),每个农产品去继承它
    在抽象出一个公共农产品工厂类(AbstractFarmProduct),每个农产品工厂去继承它,实现自己的具体实现。
    通过业务消费接口(Bussiness)调用每种操作(pick、pack等等)

  • 相关阅读:
    MES系统是如何采集Modbus设备数据的呢?
    ComponentSpace SAML Suite Crack
    红蓝对抗-红队打点的那些事
    与国自然焦虑对线的感悟
    TiDB混合部署拓扑
    普中 51 单片机点亮LED灯
    【算法练习Day31】单调递增的数字&&买卖股票的最佳时机含手续费&&监控二叉树
    C++ Reference: Standard C++ Library reference: C Library: cwchar: wcrtomb
    基于神经气体网络的图像分割与量化(Matlab代码实现)
    LC-396. 旋转函数(前缀和+滑动窗口、动态规划)
  • 原文地址:https://blog.csdn.net/qq_40965479/article/details/127409903