• 再战设计模式(二)之工厂模式


    面对对象设计的原则

    1.OCP (开闭原则 open-close principle) 一个软件类的实体 应该对扩展开放对修改关闭

    2.DIP(依赖反转原则 Dependence Inversion principle) :要针对接口编程 不要针对实现编程 通俗来讲 就是依赖于接口而不是类调用之间之间调用.

    3.LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信. 就是这个本身这个类.尽量少于别的类有关系

    工厂模式

    1.实现了调用者和创建者的分离 

    2.它的详细分类

    •  简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式

    简单工厂模式

    如果只是继承的话.调用者调用父类.也要调用子类

    接口
    /**
     * @Created by xiaodao
     */
    public interface Car {
        void run();
    }
    实现类:
    public class Byd implements Car {
        @Override
        public void run() {
            System.out.println("比亚迪.....");
        }
    }
    实现类:
    public class Audi implements Car{
        @Override
        public void run() {
            System.out.println("奥迪...在跑...");
        }
    }
    调用者:
    /**
     * @Created by xiaodao
     * 没有工厂模式的情况下.
     */
    public abstract class Client01 extends Audi implements Car {//调用者..
    
        public static void main(String[] args) {
            Car car1 = new Audi();
            Car  car2 = new Byd();
            car1.run();
            car2.run();
        }
    }
    View Code

    现在我们用单间工厂模式来实现一下..

    public  class CarFactory  {
    
        /**
         * 违反开闭原则..这里也可以直接new autiCar()
         * @param type
         * @return
         */
        public  static Car createCar(String type){
            if("audi".equals(type)){
                return new  Audi();
            }else if ("byd".equals(type)){
                return new Byd();
            }
            return  null;
        }
    }

    关于这里的判断 我们可以在做一个枚举类.或者配置一个字典项之类的实现.

    调用者

    /**
     * @Created by xiaodao
     * 简单工厂模式
     */
    public  class Client02 {//调用者..
    
        public static void main(String[] args) {
            Car car1 = CarFactory.createCar("audi");
            Car car2 = CarFactory.createCar("byd");
            car1.run();
            car2.run();
        }
    }

    这样类图虽然看起来复杂了.但是如果我们需要多加一个汽车的话.就在CarFactory里直接添加一个.就可以了.然后我们就可以调用了.哈哈,那么他是不是如名字那样一样简单

    工厂方法模式

    工厂方法虽然符合ocp原则,但是也有它的弊端.就是创建的工厂方法会很多,实际项目中用的看情况而定

    工厂方式模式与简单工厂模式最大的不同在于 ,简单工厂模式只有一个(对于一个项目或者一个独立的模块而言)工厂类,而工厂方法模式有一组实现了相同接口的工厂类

    具体接口:
    public interface Car {
        void run();
    }
    接口的实现类:
    public class Byd implements Car {
        @Override
        public void run() {
            System.out.println("比亚迪.....");
        }
    }
    接口的实现类:
    public class Audi implements Car {
        @Override
        public void run() {
            System.out.println("奥迪...在跑...");
        }
    }
    工厂的接口:
    public interface CarFactory {
        Car getCar();
    }
    工厂接口的实现:
    public class AudiFactory implements CarFactory{
        @Override
        public  Car getCar() {
            return new Audi();
        }
    }
    工厂接口的实现类:
    public class BydFactory implements CarFactory {
        @Override
        public Car getCar() {
            return new Byd();
        }
    }
    调用者的话,只需要关心使用哪个工厂实现类,而产生的.实例就可以了.
    public class Client {
        public static void main(String[] args) {
    
            Car caraudi = new AudiFactory().getCar();
            Car bydCar  = new BydFactory().getCar();
            caraudi.run();
            bydCar.run();
        }
    }

    这个就是工厂方法模式.它和静态工厂类的区别就是他遵守了OCP原则如果我们需要增加一个实现类的话.我们只需要在创建一个carFactory的实现类以及一个实现了Car的实例就好了.这样我们调用者只需要关心.CarFactory的实现类就好了

    但是这种方法如果实例多的话不好维护.

    从管理角度来说.也是各有优缺点.简单工厂模式就需要维护一个类...工厂方法模式.扩展性也非常的好.

    主要角色

    carFactory 工厂接口 

    audiFactory 工厂实现来获取audi的实例

    Car 接口 用来定义实例的属性

    audi等   具体实例的实现

    这样client 只需要用工厂实现来获取想要的实例而不需要直接和car audi等直接进行交互.具体的维护交给工厂 客户端只需要调用就可以

    抽象工厂abstract factory模式

    抽象工厂方法是用来生成不同产品族的全部产品(对于新增加的产品.很难) 抽象工厂方法主要是用来针对产品族 就是有很多产品,而不是一个产品,和简单工厂模式,根本上就不同,

    我们来举个例子,如果是前面的简单工厂方法,是针对一个汽车工厂 他可以生产很多汽车,比较单一的实现 那么抽象工厂方法就是我可以生成不同的配件(不同的工厂) 来组合成一辆汽车 需要不同的产品最终组合一个产品族 

    在企业开发中一般使用的情况很少,因为这将是一个大的工程.

    我们先来看下类的调用关

    类的结构.我这里都写在一个包下了.不够清晰:

     

    这里先说一下各自的角色

     tyreFactory 轮胎工厂生产不同的轮胎

     seatFactory 座椅工厂

     engineFactory 引擎工厂

    他们的子类就是不同的实例 生产出不同的产品

    CarAbstractFactory 抽象工厂接口 他可以生产轮胎.座椅 引擎 

    luxuryFactoryImpl 奢侈汽车工厂 可以接受不同厂家的生产的配件

    lowFactoryImpl  低端汽车工厂 也是接受各种厂家的配件

    具体生成汽车的地方可以自由的组合 这样大家是不是有点对抽象工厂了解不少?

    下面我们来上代码

    /**
     * @Created by xiaodao
     * 座椅工厂
     */
    public interface SeatFactory {
    
    
         void useSeat();
    }
    
    /**
     * @Created by xiaodao
     * 轮胎工厂
     */
    public interface TyreFactory {
    
        void useTyre();
    }
    /**
     * @Created by xiaodao
     */
    public interface EngineFactory {
    
        void useEngine();
    }
    
    
    
    /**
     * @Created by xiaodao
     * 奢侈引擎
     */
    public class LuxuryEngineFactoryImpl implements EngineFactory {
        @Override
        public void useEngine() {
            System.out.println("使用的时候奢侈引擎");
        }
    }
    
    public class LuxurySeatFactoryImpl implements SeatFactory {
        @Override
        public void useSeat() {
            System.out.println("使用的高级座椅");
        }
    }
    
    public class LuxuryTyreFactoryImpl implements TyreFactory {
        @Override
        public void useTyre() {
            System.out.println("使用奢侈轮胎");
        }
    }
    
    public class LowEngineFactoryImpl implements EngineFactory {
        @Override
        public void useEngine() {
            System.out.println("使用的是低级引擎.");
        }
    }
    
    
    public class LowSeatFactoryImpl implements SeatFactory {
        @Override
        public void useSeat() {
            System.out.println("低级座椅");
        }
    }
    
    
    public class LowTyreFactoryImpl implements TyreFactory {
        @Override
        public void useTyre() {
            System.out.println("使用低级轮胎接口");
        }
    }
    
    //抽象接口工厂
    public interface CarAbstractFactory {
    
        /**
         * 座椅工厂
         * @return
         */
        public SeatFactory createSeat();
    
    
        public EngineFactory createEngine();
    
        public TyreFactory createTyre();
    }
    
    
    
    public class LowCarFactory implements CarAbstractFactory {
        @Override
        public SeatFactory createSeat() {
            return new LowSeatFactoryImpl();
        }
    
        @Override
        public EngineFactory createEngine() {
            return new LowEngineFactoryImpl();
        }
    
        @Override
        public TyreFactory createTyre() {
            return new LowTyreFactoryImpl();
        }
    }
    
    public class LuxuryCarFactory implements CarAbstractFactory{
        @Override
        public SeatFactory createSeat() {
            return new LuxurySeatFactoryImpl();
        }
    
        @Override
        public EngineFactory createEngine() {
            return new LuxuryEngineFactoryImpl();
        }
    
        @Override
        public TyreFactory createTyre() {
            return new LuxuryTyreFactoryImpl();
        }
    }
    
    
    调用
    public class Client {
    
        public static void main(String[] args) throws IllegalAccessException, InstantiationException {
            CarAbstractFactory  luxurycar = LuxuryCarFactory.class.newInstance();
            luxurycar.createEngine().useEngine();
            luxurycar.createSeat().useSeat();
            luxurycar.createTyre().useTyre();
            CarAbstractFactory  lowcar = LowCarFactory.class.newInstance();
            lowcar.createEngine().useEngine();
            lowcar.createSeat().useSeat();
            lowcar.createTyre().useTyre();
        }
    }
    
    结果
    使用的时候奢侈引擎
    使用的高级座椅
    使用奢侈轮胎
    使用的是低级引擎.
    低级座椅
    使用低级轮胎接口
    View Code

    我们通过以上代码接口来扩展 对象的创建方式

    1. LuxuryCarFactory.class.newInstance()

    2.对象的clone()方法

    市面上有很多抽象接口的实现方式.写的代码都其实思想都是大同小异,我们主要是理解它思想.

  • 相关阅读:
    Linux之Permission denied没有权限
    soapUI的简单使用(webservice接口功能测试)
    jmeter学习(二),如何安装jmeter?
    loadrunner检查点设置失败,日志中SaveCount无法被正常统计出来
    loadrunner破解出现“license security violation,Operation is not allowed”的错误提示
    安装LoadRunner11报缺少vc2005_sp1_with_atl_fix_redist的错误
    IOS测试,打不开要测试的APP怎么办?设置信任
    Jmeter的好搭档Badboy的安装与简单使用
    映射网络驱动器会自动断开的解决方法
    oracle中如何修改用户名和密码
  • 原文地址:https://www.cnblogs.com/bj-xiaodao/p/10821230.html
Copyright © 2020-2023  润新知