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

    目标

    1. 主要是Car为例来学习工厂模式
    2. 主要是自己学习的一个记录 以前设计模式也仔细研究过没有进行整理,虽然也放在github上 已经是很久之前的事情了,这次刚好跟着课程,重新学习重新整理。

    简单工厂模式

    1. 定义 提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口,抽象类,也可以是具体的类。

    2. 本质 选择实现

    3. 实例

      下面以汽车car)为例:

    public interface Car {
        /**
         * 获取车的名字
         */
         String getName();
    }
    
    
    public class BmCar implements Car {
        /**
         * 获取车的名字
         */
        @Override
        public String getName() {
            return "宝马车";
        }
    }
    
    public class BenzCar implements Car {
        /**
         * 获取车的名字
         */
        @Override
        public String getName() {
            return "奔驰车";
        }
    }
    

    上面创建了一个Car接口和其两个实现类 BmCar和BenzCar
    如果不使用简单工厂使用该类

     @Test
        public void createCar() {
          Car car = new BmCar();
          car.getName();
        }
    

    这样调用者不仅知道接口,同时还知道实现类。这样就违背了接口的思想“封装隔离”.Car的实现类应该和调用者隔离开的,调用者根本不应该知道实现类BmCar。这个时候就可以用简单工厂.

    新增 汽车简单工厂类(CarSimpleFactory)

    public class CarSimpleFactory {
        
        private CarSimpleFactory() {
        }
    
        public static Car getCar(String name) throws Exception{
            Car car = null;
            if ("bm".equals(name)){
                car = new BmCar();
            }else if ("bc".equals(name)){
                car = new BenzCar();
            }else{
                throw new Exception("找不到要创建的Car");
            }
            return car;
        }
    }
    

    调用代码如下:

    @Test
    public void  createCarBySimpleFactory() throws Exception {
        Car car = CarSimpleFactory.getCar("bm");
        car.getName();
    }
    

    工厂方法模式

    1. 定义
      工厂方法模式(FACTORYMETHOD)是一种常用的对象创建型设计模式,此模式的核心精神是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。
    2. 本质 延迟到子类来选择实现
    3. 实例 还是以Car为例

    CarFuncFactory

    public abstract class CarFuncFactory {
    
        /**
         * 获取
         * @return car
         */
        protected abstract Car getCar();
    
        public String showName(){
            Car car = getCar();
            return car.getName();
        }
    }
    

    BmCarFuncFactory

    public class BmCarFuncFactory extends CarFuncFactory {
        /**
         * 获取
         *
         * @return car
         */
        @Override
        public Car getCar() {
            return new BmCar();
        }
    }
    
    

    BenzCarFuncFactory

    public class BenzCarFuncFactory extends CarFuncFactory {
        /**
         * 获取
         *
         * @return car
         */
        @Override
        public Car getCar() {
            return new BenzCar();
        }
    }
    

    调用

        @Test
        public void  createCarByFuncFactory(){
            CarFuncFactory funcFactory = new BmCarFuncFactory();
            System.out.println(funcFactory.showName());
    
        }
    

    抽象工厂

    1. 定义 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类!
    2. 本质 选择产品簇的实现
    3. 实例 随着造成工厂规模不断扩大现在造车场可以同时奔驰和宝马车。

    AbstractFactory

    public interface AbstractFactory {
        /**
         * 获取宝马对象
         * @return Car
         */
        Car getBmCar();
    
        /**
         * 获取奔驰对象
         * @return Car
         */
        Car getBenzCar();
    
    }
    

    CarFactory

    public class CarFactory implements AbstractFactory {
        /**
         * 获取宝马对象
         *
         * @return
         */
        @Override
        public Car getBmCar() {
            return new BmCar();
        }
    
        /**
         * 获取奔驰对象
         *
         * @return
         */
        @Override
        public Car getBenzCar() {
            return new BenzCar();
        }
    }
    
    

    调用

     @Test
        public  void createCarAbstrFactory(){
            AbstractFactory carFactory = new CarFactory();
            carFactory.getBenzCar().getName();
            carFactory.getBmCar().getName();
        }
    

    以上创建两种类型的car只能像如上代码那,用抽象工厂创建两次 其实我们可以引入一个角色叫Car工程师,由工程师来同时创建奔驰和宝马车。如下提供加入工程师的角色的代码。

    CarEngineer

    public class CarEngineer {
        /**
         *宝马
         */
        private BmCar bmCar =null;
    
        /**
         *奔驰
         */
        private BenzCar benzCar = null;
    
        public void makeCar(AbstractFactory abstractFactory) throws Exception {
    
            //获取宝马Car
            this.bmCar = abstractFactory.getBmCar();
    
            //获取奔驰Car
            this.benzCar =  abstractFactory.getBenzCar();
    
        }
    }
    

    调用

     @Test
        public  void createCarAbstrFactoryRef() throws Exception {
            CarEngineer carEngineer = new CarEngineer();
            AbstractFactory abstractFactory = new CarFactory();
            carEngineer.makeCar(abstractFactory);
        }
    

    其实如上设计还存在一个问题如果我想加入一个类型的车 抽象工厂需要改变 抽象工厂的实现也要改变,这样其实很麻烦。比如我们这个工厂随着技术实力越来越强可以造BL汽车。这样就要修改抽象工厂和实现了!采用如下解决方式!抽象类添加一个参数。

    BlCar

    public class BlCar implements Car {
        /**
         * 获取车的名字
         */
        @Override
        public String getName() {
            return "宾利汽车";
        }
    }
    
    

    AbstractFactoryExtra

    public interface AbstractFactoryExtra {
        /**
         * 获得车
         * @param type
         * @return
         */
        public Car getCar(int type) throws Exception;
    }
    

    CarFactoryExtra

    public class CarFactoryExtra implements AbstractFactoryExtra{
        /**
         * 获得车
         *
         * @param type
         * @return
         */
        @Override
        public Car getCar(int type) throws Exception {
            Car car = null;
            if (type == 1) {
                car = new BmCar();
            } else if (type == 2) {
                car = new BenzCar();
            } else if (type == 3) {
                car = new BlCar();
            }else {
                throw new Exception("找不到!");
            }
            return car;
        }
    }
    

    CarEngineerExtra

    public class CarEngineerExtra {
        /**
         *宝马
         */
        private BmCar bmCar =null;
    
        /**
         *奔驰
         */
        private BenzCar benzCar = null;
    
        /**
         *奔驰
         */
        private BlCar blCar = null;
    
        public void makeCar(AbstractFactoryExtra abstractFactoryExtra) throws Exception {
    
            //获取宝马Car
            this.bmCar = (BmCar) abstractFactoryExtra.getCar(1);
    
            //获取奔驰Car
            this.benzCar = (BenzCar) abstractFactoryExtra.getCar(2);
    
            //获取宾利Car
            this.blCar = (BlCar) abstractFactoryExtra.getCar(3);
        }
    
    }
    

    调用

        @Test
        public  void createCarAbstrFactoryExtra() throws Exception {
            CarEngineerExtra carEngineer = new CarEngineerExtra();
            AbstractFactoryExtra abstractFactoryExtra = new CarFactoryExtra();
            carEngineer.makeCar(abstractFactoryExtra);
        }
    https://github.com/ljmomo/learn-pattern.git
    https://github.com/ljmomo/learn-pattern.git
    ht
  • 相关阅读:
    ZOJ 1002 Fire Net
    Uva 12889 One-Two-Three
    URAL 1881 Long problem statement
    URAL 1880 Psych Up's Eigenvalues
    URAL 1877 Bicycle Codes
    URAL 1876 Centipede's Morning
    URAL 1873. GOV Chronicles
    Uva 839 Not so Mobile
    Uva 679 Dropping Balls
    An ac a day,keep wa away
  • 原文地址:https://www.cnblogs.com/mokingone/p/9109014.html
Copyright © 2011-2022 走看看