public class BusAccessories implements Accessories {
BusAccessories() {
this.make();
}
@Override
public void make() {
System.out.println("制造公交车配件");
}
}
1、 抽象工厂模式的定义
抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。——摘自百度百科
2、抽象工厂模式的流程
这里举例子帮助大家理解:
总体需求是:生产两款交通工具Bus以及Car,Bus类以及Car类又分别需要生产车主体以及对应配件两种相互关联的产品。
设计思路:
首先定义一个抽象的工厂接口,负责告诉具体的工厂:你需要生产的类型。因为是用的接口类型,所以对应执行的代码块功能非常单一,扩展性强,闭合性高(再次感叹java接口功能的强大)
public interface AbstractFactory {
Vehicle makeVehicle();//生产交通工具类
Accessories makeAccessories();//生产交通工具配件类
}
接着因为需要生产两个类的产品:Car类、Bus类。
通常工厂生产模式中:对应的一个工厂生产一种类别的产品。这里有两个类,因此需要建立两个工厂:CarFactory、BusFactory
前方高能!!
两个厂在接入抽象工厂接口后,代码块变得异常简洁,只需要根据接口的内容去new对象即可。(客户端不再负责对象的创建,而是把这个责任丢给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责。并且当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且,如果要更换这一系列的产品,则只需要更换一个工厂类即可——括号内摘自百度百科)
补充:为什么当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单?那是因为只要在抽象工厂接口处再提供相关联的产品方法即可,相当方便!
public class CarFactory implements AbstractFactory {
@Override
public Vehicle makeVehicle() {
return new Car();
}
@Override
public Accessories makeAccessories() {
return new CarAccessories();
}
}
public class BusFactory implements AbstractFactory {
@Override
public Vehicle makeVehicle() {
return new Bus();
}
@Override
public Accessories makeAccessories() {
return new BusAccessories();
}
}
到这里工厂的生产框架就搭建起来了:
工厂BusFactory输出new Bus、new BusAccessories
工厂CarFactory输出new Car、new CarAccessories
但是工厂需要怎么具体去生产以上new出来的具体产品呢?
这里需要给到工厂一个具体的生产流程——生产流程定义在Car类对象以及Bus类对象的构造方法中,确保new出对象的同时,工厂就能同步执行相应的流水线操作。
我这里选择用接口的方式把具体执行流程的逻辑代码写在接口里,然后在间接插入Car类以及Bus类的构造方法中
配件类:抽象标准方法
public interface Accessories {
void make();//制造对应配件的方法
}
汽车配件类:流水线具体实现流程
public class CarAccessories implements Accessories {
CarAccessories() {
this.make();
}
@Override
public void make() {
System.out.println("制造汽车配件");
}
}
公交配件类:流水线具体实现流程
public class BusAccessories implements Accessories {
BusAccessories() {
this.make();
}
@Override
public void make() {
System.out.println("制造公交车配件");
}
}
交通工具类:抽象标准方法
public interface Vehicle {
void make();//制造对应交通工具的方法
}
汽车类:流水线具体实现流程
public class Car implements Vehicle {
public Car() {
this.make();
}
@Override
public void make() {
System.out.println("制造一辆汽车");//制造汽车流程省略
}
}
公交类:流水线具体实现流程
public class Bus implements Vehicle {
Bus() {
this.make();
}
@Override
public void make() {
System.out.println("制造一辆公交车");//制造公交车流程省略
}
}
制造方法就绪,两个工厂就可以正常生产产品了。
运行端:
public class Test {
public static void main(String[] args) {
AbstractFactory carfactory = new CarFactory();
AbstractFactory busfactory = new BusFactory();
carfactory.makeAccessories();
busfactory.makeAccessories();
carfactory.makeVehicle();
busfactory.makeVehicle();
}
}
制造汽车配件
制造公交车配件
制造一辆汽车
制造一辆公交车
优点
(1)分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。 [3]
(2)易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。 [3]
(3)有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。 [3]
缺点
难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。 [3]