zoukankan      html  css  js  c++  java
  • 设计模式_工厂模式

    模式:创建型模式

    ✨ 普通的工厂模式
    优点:编写简单,清晰
    缺点:当工厂需要生产多一个车型,那就需要更改“工厂类”的代码,这样对开闭原则不好。

    /**
     * 车的接口
     * */
    public interface Car {
        public void drive();
    }
    
    
    /**
     * 奔驰
     * */
    class Benz implements Car{
    
        @Override
        public void drive() {
            System.out.println("Benz");
        }
    }
    
    /**
     * 宝马
     * */
    class BMW implements Car{
    
        @Override
        public void drive() {
            System.out.println("BMW");
        }
    }
    
    class CarFactory { 
        public Car productCar(String car) {
            if ("Benz".equals(car)) {
                return new Benz();
            } else if("BMW".equals(car)) {
                return new BMW();
            } 
            
            return null;
        }
    }
    

    ✨ 工厂方法模式
    优点:解决了“普通工厂方法”中破坏的开闭原则。为了阻止“增加一个牌子就需要改一下工厂源码”,我们决定换个思路来解决这个问题-“增加类”。当需要增加一个牌子的时候,我们就相应增加一个工厂类。利用 Java 多态特性来解决这个问题。

    我们继续使用上面的代码作为这个栏目的示例。

    /**
     * 比亚迪
     * */
    class BYD implements Car{
    
        @Override
        public void drive() {
            System.out.println("BYD");
        }
    }
    

    我们将相关的车辆抽象成一个工厂

    /**
     * 工厂接口
     * */
    interface Factory {
        void product() ;
    }
    

    然后生成一个"比亚迪"的工厂

    /**
     * 比亚迪 - 工厂
     * */
    class BYDFactory implements Factory {
        @Override
        public BYD product() {
            return new BYD();
        }
    }
    

    然后当我们想生产一个比亚迪的车辆,我们只需要这么写

    class Test {
    	public static void main(String[] args) {
    	    Factory factory = new BYDFactory();
            factory.product();
    	}
    }
    

    同理,若我们再向增加多一个车辆的牌子生产,我们只需要遵循以下步骤

    1. 增加相关的汽车类,实现 C调用其product方法即可。
      ar 接口
    2. 增加相关汽车类的工厂,实现 Factory
    3. 通过实例化新增的汽车类的工厂类
      这样做的好处是,当我们新增的类的时候,不需要更改源码,只需要增加相关的类。

    但是这个模式还是不够完美。比如说,我想要一个 beaz 牌子的轮胎,我就加一个 beaz 的相关类及工厂类;我想要一个 beaz 牌子的轮胎,我就加一个 BYD 的相关类及工厂类...
    太可怕了。这样子加的类只会越来越多。
    那该怎么办?
    或许有人已经注意到了,其实无论是轮胎还是后视镜,只要你想要的是 beaz 这个牌子的产品,那么我们可以以牌子为维度来抽象。所以不仅仅是产品(如 beaz 轮胎)可以抽象,其实工厂也可以抽象!下面将讲解对工厂的抽象。

    ✨ 抽象工厂模式
    既然 beaz 不仅仅生产汽车,它还生产方向盘,雨刷,轮胎等等。所以我们可以认为抽象出一个工厂接口,定义好这个
    这类抽象的方法。

    public interface CarFactory {
        void createCar();
        Screen createScreen();
        AimingCircle createAimingCircle();
    }
    
    /**
     * 屏幕抽象
     * */
    interface Screen {
    }
    
    /** 方向盘接口 */
    interface AimingCircle {
    
    }
    /** 奔驰屏幕实现 */
    class BenzScreen implements Screen {
    
    }
    /** 奔驰方向盘实现 */
    class BenzAimingCircle implements AimingCircle {
    
    }
    /** 比亚迪屏幕实现 */
    class BYDScreen implements Screen {
    
    }
    /** 比亚迪方向盘实现 */
    class BYDAimingCircle implements AimingCircle {
    
    }
    
    /** 奔驰 一系列工厂 */
    class BenzFactory implements CarFactory {
    
        @Override
        public void createCar() {
            System.out.println("创建一辆奔驰车");
        }
    
        @Override
        public Screen createScreen() {
            return new BenzScreen();
        }
    
        @Override
        public AimingCircle createAimingCircle() {
            return new BenzAimingCircle();
        }
    }
    
    /** BYD 一系列工厂 */
    class BYDFactory implements CarFactory {
    
        @Override
        public void createCar() {
            System.out.println("创建一辆奔驰车");
        }
    
        @Override
        public Screen createScreen() {
            return new BYDScreen();
        }
    
        @Override
        public AimingCircle createAimingCircle() {
            return new BYDAimingCircle();
        }
    }
    

    其实细心一点的同学就会发现,其实工厂抽象工厂之间的不同之处在于,工厂的抽象维度在于产品,一个工厂只能生产一个产品;而抽象工厂的抽象维度在于工厂,这个工厂是可以生产多系列的产品。

  • 相关阅读:
    自我介绍
    币值转换
    打印沙漏
    对我影响最大的三位老师

    pta
    pta-3
    学习计划
    对我有影响的三个老师
    介绍自己
  • 原文地址:https://www.cnblogs.com/tjc1996/p/10671080.html
Copyright © 2011-2022 走看看