Java设计模式之抽象工厂模式
- 抽象工厂模式介绍
抽象工厂模式是创建型设计模式之一,在之前的学习中,我们已经了解了工厂方法模式,那么这个抽象工厂模式又是什么呢?大家可以联想一下现实中的工厂肯定都是具体的,也就是说每个工厂都会生产某一种具体的产品,那么抽象工厂意味着生产出来的产品是不确定的,那这样是不是很奇怪呢?其实定义这种设计模式,是非常方便的,因为我们都知道,如在Android中,有对应的Button和TextView,在IOS中也有对应的Button和TextView 在Windows Phone中也有对应的Button和TextView等,但是每个不同的系统中,Button和TextView的实现会不一样,所以,这个时候用抽象工厂模式来设计,就可以来统一管理了。 - 抽象工厂模式的定义
为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体类 - 抽象工厂模式的使用场景
一个对象组有相同的约束时可以使用抽象工厂模式,是不是听起来是很抽象?其实就像上面的例子中,不同的系统下Button和TextView的具体逻辑是不一样的。这是时候我们就考虑使用抽象工厂模式来设计Android、Ios、Windows Phone的Button和TextView。 - 抽象工厂模式的UML类图
对于抽象工厂模式,其主要也是四个角色:
AbstractFactory:抽象工厂角色,它声明了一组用于生产一种产品的方法,每个方法对应一种产品,如上图中的抽象工厂中就定义了三个方法,分别生产A,生产B,生产C。
ConcreteFactory:具体工厂角色,实现每个抽象工厂中定义的生产产品的方法,生成一组具体产品,这些产品构成一个产品种类,每一个产品都位于某个产品等级结构中。
AbstractProduct:抽象产品角色,它为每种产品声明的接口。
ConcreteProduct:具体产品角色,它定义具体工厂生产的具体产品类,实现抽象产品接口中声明的业务方法。
5. 抽象工厂模式的简单实现
还是拿上次的那个小米工厂来举例子,假设小米手机中都要有内存,cpu,屏幕,假设生产小米4手机,需要2G的运行内存,cpu为高通骁龙801(MSM8974AC),屏幕是5.0的,而生产小米NOTE则需要3G的运行内存,cpu2.5Ghz高通801四核,屏幕为5.7,通过这个例子,我们来实现一下抽象工厂模式。
ABSMIFactory .java
/**
* 抽象工厂
*/
public abstract class ABSMIFactory {
/**
* 生产内存卡
*/
public abstract IMemory produceMemory();
/**
* 生产CPU
*/
public abstract ICPU produceCPU();
/**
* 生产屏幕
*/
public abstract IScreen produceScreen();
}
ICPU.java
/**
* CPU接口
*/
public interface ICPU {
void cpu();
}
MI4CPU .java
/**
* 具体的小米4CPU产品类
*/
public class MI4CPU implements ICPU {
@Override
public void cpu() {
System.out.println("小米4的高通骁龙801(MSM8974AC)CPU");
}
}
MINoteCPU .java
/**
* 具体的小米NoteCPU产品类
*/
public class MINoteCPU implements ICPU {
@Override
public void cpu() {
System.out.println("小米Note的2.5Ghz高通801四核CPU");
}
}
IMemory .java
/**
* 内存接口
*/
public interface IMemory {
void memory();
}
MI4Memory .java
/**
* 具体的小米4内存产品类
*/
public class MI4Memory implements IMemory {
@Override
public void memory() {
System.out.println("小米4的2G运行内存");
}
}
MINoteMemory .java
/**
* 具体的小米Note内存产品类
*/
public class MINoteMemory implements IMemory {
@Override
public void memory() {
System.out.println("小米Note的3G运行内存");
}
}
IScreen .java
/**
* 屏幕接口
*/
public interface IScreen {
void screen();
}
MI4Screen .java
/**
* 具体的小米4屏幕产品类
*/
public class MI4Screen implements IScreen {
@Override
public void screen() {
System.out.println("小米4的5.0屏幕");
}
}
MINoteScreen .java
/**
* 具体的小米Note屏幕产品类
*/
public class MINoteScreen implements IScreen {
@Override
public void screen() {
System.out.println("小米Note的5.7屏幕");
}
}
ConcreteMI4Factory .java
/**
* 具体的小米4工厂
*/
public class ConcreteMI4Factory extends ABSMIFactory {
/**
* 生产内存
* @return 返回生产的小米4内存产品
*/
@Override
public IMemory produceMemory() {
return new MI4Memory();
}
/**
* 生产CPU
* @return 返回生产的小米4CPU产品
*/
@Override
public ICPU produceCPU() {
return new MI4CPU();
}
/**
* 生产屏幕
* @return 返回生产的小米4屏幕产品
*/
@Override
public IScreen produceScreen() {
return new MI4Screen();
}
}
ConcreteMINoteFactory .java
/**
* 具体的小米Note工厂类
*/
public class ConcreteMINoteFactory extends ABSMIFactory {
/**
* 生产小米Note内存产品
* @return 返回生产小米Note的内存产品
*/
@Override
public IMemory produceMemory() {
return new MINoteMemory();
}
/**
* 生产小米NoteCPU产品
* @return 返回生产小米Note的CPU产品
*/
@Override
public ICPU produceCPU() {
return new MINoteCPU();
}
/**
* 生产小米Note屏幕产品
* @return 返回生产小米Note的屏幕产品
*/
@Override
public IScreen produceScreen() {
return new MINoteScreen();
}
}
Text .java
/**
* 测试类
*/
public class Text {
public static void main(String[] args) {
//创建具体的小米4工厂类
ConcreteMI4Factory mi4Factory = new ConcreteMI4Factory();
//生产小米4内存
mi4Factory.produceMemory().memory();
//生产小米4CPU
mi4Factory.produceCPU().cpu();
//生产小米4屏幕
mi4Factory.produceScreen().screen();
System.out.println("*************************");
//创建具体的小米Note工厂类
ConcreteMINoteFactory miNoteFactory = new ConcreteMINoteFactory();
//生产小米Note内存
miNoteFactory.produceMemory().memory();
//生产小米NoteCPU
miNoteFactory.produceCPU().cpu();
//生产小米Note屏幕
miNoteFactory.produceScreen().screen();
}
}
对于上面的代码,我们只是模拟了小米4和小米Note工厂,如果此时我们需要增加小米3或者小米Note顶配版的工厂,那么对应的生产具体的内存、CPU、屏幕类我们又要再一次的创建,所以从这里我们可以看出抽象工厂模式的缺点,就是类的增加,如果工厂类过多,势必导致类文件非常多,因此在实际的开发中一定要权衡使用。