创建型设计模式之抽象工厂模式

介绍

在前面已经讲解过工厂方法模式,这俩者有什么区别呢?前面所说的工厂方法模式只会生产一种具体的产品,而抽象工厂模式生产出来的产品是不确定的。例如不同操作系统中控件的实现不一样,展示效果也不一样,对于操作系统如Android,iOS,WindowPhone本身构成一个产品类,而其控件如Button,TextView也构成产品类,两种产品类两种变化,各有各的特性。

定义

为创建一组相关或者相互依赖的对象提供一个接口,而不需要指定它们的具体类。

使用场景

一个对象族有相同约束时可以使用抽象工厂方法。举个例子:Android,iOS,Phone下都有Button,TextView,两者属于控件的范围,但是它们所在操作系统不一样,所以代码逻辑实现也是不一样的,这时就可以考虑使用抽象工厂方法模式来生产Android,iOS,phone下控件。

类图

创建型设计模式之抽象工厂模式_第1张图片

 

角色介绍:

虽然抽象工厂方法种类繁多,但是主要分成四类:

  • AbstractFactory - 抽象工厂角色,它声明一组用于创建一种产品的方法,每个产品对应一种方法,如上图的AbstractFactory类中就定义了俩个方法,分别创建产品A和产品B
  • ConcreteFactory - 具体工厂角色,实现抽象工厂中定义的创建产品的方法,生成一组具体的产品,这些产品构成一个产品种类,每一个产品都位于某个产品等级结构中,如上述类图中的ConcreteFactory1和ConcreteFactory2
  • AbstractProduct - 抽象产品角色,它为每种产品声明接口,比如上图中的AbstractProductA和AbstractProductB
  • ConcreteProduct - 具体产品角色,它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法,如上图中的ConcreteProductA1等

简单实现

在工厂方法模式中,我们生产了三种车型,虽然整体流程一样,但是各个车型的零件差别很大,而且厂家也不一样,三种车型对应是一系列车,而零件比如轮胎、发动机、制动系统等对应的是一系列零件部件,两者是俩种不同的产品类型,这时候就可以将抽象工厂模式运用到其中。

首先汽车需要生产轮胎,发动机,制动系统这三种部件

轮胎相关类

抽象产品角色

public abstract class Tire {
    public abstract void tire();
}

具体产品角色 

public class NormalTire extends Tire {
    @Override
    public void tire() {
        System.out.println("普通轮胎");
    }
}
public class SUVTire extends Tire {
    @Override
    public void tire() {
        System.out.println("越野轮胎");
    }
}

发动机相关类

抽象产品角色

public abstract class Engine {
    public abstract void engine();
}

具体产品角色  

public class DomesticEngine extends Engine {
    @Override
    public void engine() {
        System.out.println("国产发动机");
    }
}
public class ImportEngine extends Engine {
    @Override
    public void engine() {
        System.out.println("进口发动机");
    }
}

制动系统相关类

抽象产品角色 

public abstract class Brake {
    public abstract void brake();
}

具体产品角色   

public class NormalBrake extends Brake {
    @Override
    public void brake() {
        System.out.println("普通制动");
    }
}
public class SeniorBrake extends Brake {
    @Override
    public void brake() {
        System.out.println("高级制动");
    }
}

有了零件就要有工厂生产 

抽象汽车工厂,即抽象工厂角色

public abstract class CarFactory {
    public abstract Tire createTire();//生产轮胎
    public abstract Engine createEngine();//生产发动机
    public abstract Brake createBrake();//生产制动
}

每种车型的零件部件不同

奥迪工厂, 具体工厂角色

public class AudiCarFactory extends CarFactory {

    @Override
    public Tire createTire() {
        return new NormalTire();
    }

    @Override
    public Engine createEngine() {
        return new DomesticEngine();
    }

    @Override
    public Brake createBrake() {
        return new NormalBrake();
    }
}

奔驰工厂, 具体工厂角色

public class BenzCarFactory extends CarFactory {

    @Override
    public Tire createTire() {
        return new SUVTire();
    }

    @Override
    public Engine createEngine() {
        return new ImportEngine();
    }

    @Override
    public Brake createBrake() {
        return new SeniorBrake();
    }
}

宝马工厂, 具体工厂角色

public class BWMCarFactory extends CarFactory {

    @Override
    public Tire createTire() {
        return new NormalTire();
    }

    @Override
    public Engine createEngine() {
        return new ImportEngine();
    }

    @Override
    public Brake createBrake() {
        return new SeniorBrake();
    }
}

最后在一个Client中模拟

public class Client {

    public static void main(String[] args){
         //创建一个生产奥迪的工厂
         CarFactory carFactoryAudi = new AudiCarFactory();
         carFactoryAudi.createTire().tire();
         carFactoryAudi.createEngine().engine();
         carFactoryAudi.createBrake().brake();
         System.out.println();
        //创建一个生产奔驰的工厂
         CarFactory carFactoryBenz = new BenzCarFactory();
        carFactoryBenz.createTire().tire();
        carFactoryBenz.createEngine().engine();
        carFactoryBenz.createBrake().brake();
        System.out.println();
        //创建一个生产宝马的工厂
        CarFactory carFactoryBWM = new BWMCarFactory();
        carFactoryBWM.createTire().tire();
        carFactoryBWM.createEngine().engine();
        carFactoryBWM.createBrake().brake();
    }
}

输出结果

普通轮胎
国产发动机
普通制动

越野轮胎
进口发动机
高级制动

普通轮胎
进口发动机
高级制动

上面只是模拟生产三种车系的情况,如果要生产其他车系,就要增加其他车系的工厂,不同车系构成一个产品类。如果对于奥迪工厂,我们把普通轮胎换成越野轮胎,虽然生产出来的车还是奥迪车型,但零件又和原本第一次生产出来的不一样,不同零件又构成一个产品类。两种产品类两种变化。

总结

我们在开发中很少会出现多个产品种类的情况,大部分情况我们使用工厂方式模式就可以解决。

优点:

分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本不知道具体的实现类是谁,使其从具体的产品实现中解耦。

缺点:

(1)类文件变多

(2)每当增加一个产品类就要修改抽象工厂,那么所有具体的工厂类均会被修改,不容易扩展新的产品类

 本文源码位置

你可能感兴趣的:(设计模式)