设计模式—创建型模式之工厂模式
工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。
简单工厂模式
比如我们有造车的工厂,来生产车,我们先定义一个抽象车产品:
//抽象车产品类
public abstract class AbstractCar { 
    String engine;
    public abstract void run();
}
 
我们有两个具体的产品,货车和家用小汽车,都继承自抽象车:
//货车
public class Truck extends AbstractCar{
	public Truck() {
        this.engine = "货车引擎";
    }
    @Override
    public void run() {
        System.out.println(this.engine+"--->正在运行");
    }
}
//家用小汽车
public class MiniCar extends AbstractCar{
    public MiniCar() {
        this.engine = "家用小汽车引擎";
    }
    @Override
    public void run() {
        System.out.println(this.engine + "----------》正在运行");
    }
}
 
那我们的工厂可以如此定义:
public class MySimpleFactory {
   	/**
     * 获取车
     * @param type
     * @return
     */
    public AbstractCar newCar(String type){
        if("truck".equals(type)){
            return new Truck();
        }else if("mini".equals(type)){
            return new MiniCar();
        }
        return null;
    }
}
 
一般简单工厂生产的产品优先。
测试类如下:
public class SimpleFactoryTest {
    public static void main(String[] args) {
        MySimpleFactory factory = new MySimpleFactory();
        AbstractCar truck = factory.newCar("truck");
        AbstractCar mini = factory.newCar("mini");
        truck.run();
        mini.run();
    }
}
 
运行如下:

缺点
**违反了开闭原则,扩展不易。**如果有大量的产品,会有大量的if else。
工厂方法模式
因为简单工厂模式,会出现大量的if else,并不能满足打开扩展、关闭修改的原则,我们希望,如果有扩展,直接扩展一个类就好,不区改动创造类型的代码,这样工厂方法模式就出现了。我们可以把工厂再进行抽象,把我们的工厂提升一个层次。
抽象类或者接口,就会有多个实现;有多实现 就会有多功能。
抽象工厂如下:
public abstract class AbstarctCarFactory {
    public abstract AbstractCar newCar();
}
 
我们的货车、小汽车,分别由不同的工厂来创建:
//货车工厂
public class TruckFactory extends AbstarctCarFactory {
    @Override
    public AbstractCar newCar() {
        return new Truck();
    }
}
//小汽车工厂
public class MiniCarFactory extends AbstarctCarFactory {
    @Override
    public AbstractCar newCar() {
        return new MiniCar();
    }
}
 
测试类如下:
public class FactoryMethodTest {
    public static void main(String[] args) {
        AbstarctCarFactory miniCarFactory = new MiniCarFactory();
        AbstractCar miniCar = miniCarFactory.newCar();
        miniCar.run();
        TruckFactory truckFactory = new TruckFactory();
        AbstractCar truck = truckFactory.newCar();
        truck.run();
    }
}
 
运行结果如下:

这样,如果我们有新的类型,可以直接继承这个抽象工厂即可。
缺点
系统复杂度增加,可创建的品类单一。
抽象工厂模式
我们先来区分两个概念:
- 产品等级:比如手机可以分为低配版手机、高配版手机;产品等级结构即产品的继承结构,如抽象类为手机,可以有拍照手机、游戏手机等等。
 - 产品族:产品可以分为手机、汽车等,这是产品族。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。
 
在车的产品基础上,我们又增加了新的产品,手机。
public abstract class AbstractPhone {
    //手机类型
    String type;
    public abstract void run();
}
public class GamePhone extends AbstractPhone {
    public GamePhone() {
        this.type = "游戏手机";
    }
    @Override
    public void run() {
        System.out.println(this.type + "正在运行了...");
    }
}
public class MyPhotoPhoneFactory implements MyAbstarctFactory{
    @Override
    public AbstractPhone newPhone() {
        return new PhotoPhone();
    }
}
 
如果我们想生产车和手机,我们可以定义抽象工厂:
public interface  MyAbstarctFactory {
    default AbstractCar newCar(){
        return null;
    }
    default AbstractPhone newPhone(){
        return null;
    }
}
 
生产手机的工厂分别为:
public class MyGamePhoneFactory implements MyAbstarctFactory{
    @Override
    public AbstractPhone newPhone() {
        return new GamePhone();
    }
}
public class MyPhotoPhoneFactory implements MyAbstarctFactory{
    @Override
    public AbstractPhone newPhone() {
        return new PhotoPhone();
    }
}
 
生产车的工厂分别为:
public class MyMiniCarFactory implements MyAbstarctFactory{
    @Override
    public AbstractCar newCar() {
        return new MiniCar();
    }
}
public class MyTruckCarFactory implements MyAbstarctFactory{
    @Override
    public AbstractCar newCar() {
        return new Truck();
    }
}
 
测试类如下:
public class MyTest {
    public static void main(String[] args) {
        MyAbstarctFactory factory = new MyGamePhoneFactory();
        AbstractPhone abstractPhone = factory.newPhone();
        abstractPhone.run();
        factory = new MyMiniCarFactory();
        AbstractCar abstractCar = factory.newCar();
        abstractCar.run();
    }
}
 
运行如下:

可以看到,我们在扩展时,都是新增类,而不是修改原有的方法。



















