抽象工厂模式介绍
抽象工厂模式(Abstract Factory Pattern),也是创建型设计模式之一。在上一篇中我们介绍了工厂方法模式
那么这个抽象工厂又是怎么一回事呢?
大家联想一下现实生活中的工厂肯定都是具体的,也就是说每个工厂都会生产某一种具体的产品,那么抽象工厂意味着生产出来的产品是不确定的,那这岂不是很奇怪? 抽象工厂模式起源于以前对不同抽象系统的图形化解决方案,如不同操作系统中的按钮和文本控件是不一样的,其实现不同,展示效果也不同。对于一个操作系统,其本身就构成一个产品类,而按钮和文本控件也构成一个产品类,两种产品类两种变化,各自有自己的特性,如Android中的Button和TextView,iOS中的Button和TextView,window Phone中的Button和TextView等
抽象工厂模式的定义
为创建一组相关或者相互依赖的对象提供一个接口,而不需要指定它们的具体类。
抽象工厂模式的使用场景
一个对象族有相同的约束时可以使用抽象工厂模式。是不是听起来很抽象? 举个例子,Android,iOS,Window Phone下都有短信软件和拨号软件,两者都属于Software软件的范畴,但是,它们所在的操作系统平台不一样,即便是同一家公司出品的软件,其代码的实现逻辑也是不同的,这时候就可以考虑使用抽象工厂方法模式来产生Android,iOS,Window Phone下的短信软件和拨号软件。
抽象工厂方法模式的简单实现
在上一篇所讲的工厂方法模式中,以小李的车厂为例阐述了工厂方法模式,但是,后来小李发现一个问题,虽然Q3,Q5,Q7都是一个车系,但是三者之间的零部件差别却是很大的,就拿Q3和Q7来说,Q3使用的发动机是国产的,Q7使用的则是原装进口的;Q3的轮胎是普通的轮胎,而Q7则使用的是全尺寸的越野轮胎;还有Q3使用的是比较普通的制动系统,而Q7则使用的是制动性能极好的制动系统。Q3,Q7对应的是一系列车,而发动机,轮胎,制动系统则对应的是一系列零部件,两者是两种不同的产品类型,这时候就可以将抽象工厂模式应用在其中,首先,汽车工厂需要生产轮胎,发动机,制动系统这3种部件。
代码实现如下所示:
// 抽象车厂类
public abstract class CarFactory{
/**
*生产轮胎
*
*@return 轮胎
*/
public abstract ITire createTire();
/**
*生产发动机
*
*@return 发动机
*/
public abstract IEngine createEngine();
/**
*生产制动系统
*
*@return 制动系统
*/
public abstract IBrake createBrake();
}
/**
*这里我们为每一种零部件产品定义一个接口,并分别创建两个不同的实现类表 示不同的零部件产品。
*
*/
//轮胎相关类
public interface ITire{
/**
*轮胎
*/
void tire();
}
public class NormalITire implements ITire{
@Override
public void tire(){
System.out.println("普通轮胎");
}
}
public class SUVTire implements Itire{
@Override
public void tire(){
System.out.println("越野轮胎");
}
}
//发动机相关类
public interface IEngine{
/**
*发动机
*/
void engine();
}
public class ChinaEngine implements IEngine{
@Override
public void engine(){
System.out.println("国产发动机");
}
}
public class ImportEngine implements IEgine{
@Override
public void engine(){
System.out.println("进口发动机");
}
}
//制动系统相关类
public interface IBrake{
/**
*制动系统
*/
void brake();
}
public class NormalBrake implements IBrake{
@Override
public void brake(){
System.out.println("普通制动");
}
}
public class SeniorBrake implements IBrake{
@Override
public void brake(){
System.out.println("高级制动");
}
}
/**
*
*对于生产Q3的工厂,其使用的零部件不同,而生产Q7的工厂呢,其零部件也 不同。
*
*/
//Q3工厂类
public class Q3Factory extends CarFactory{
@Override
public ITire createTire(){
return new NormalTire();
}
@Override
public IEngine createEngine(){
return new ChinaEngine();
}
@Override
public IBrake createBrake(){
return new NormalBrake(){
}
}
//Q7工厂类
public class Q3Factory extends CarFactory{
@Override
public ITire createTire(){
return new SUVTire();
}
@Override
public IEngine createEngine(){
return new ImportEngine();
}
@Override
public IBrake createBrake(){
return new SeniorBrake(){
}
}
/**
*
*最后我们在一个Client客户类中模拟
*
*/
//客户类
public class Client {
public void void main(String[] args){
//构造一个生产Q3的工厂
CarFactory factoryQ3=new Q3Factory();
factoryQ3.createTire().tire();
factoryQ3.createEngine.engine();
factoryQ3.createBrake.brake();
//构造一个生产Q7的工厂
CarFactory factoryQ7=new Q3Factory();
factoryQ7.createTire().tire();
factoryQ7.createEngine.engine();
factoryQ7.createBrake.brake();
}
}
输出结果如下:
普通轮胎
国产发动机
普通制动
越野轮胎
进口发动机
高级制动
总结
上面我们只是模拟了两个车系Q3和Q7的工厂,如果此时我们需要增加Q5的工厂呢? 那么定义的轮胎,制动系统和发动机类有要增加,这里就可以看出抽象工厂方法模式的一个弊端,就是类的徒增,如果工厂类过多,势必导致类文件非常多,因此,在实际开发中一定要权衡慎用