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

面对对象设计的原则

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()方法

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