抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。
一、实现
(一)抽象产品
1.定义人类接口,包含哭、笑、说话、性别四个属性
/**
* 抽象人类,四个属性
* @author EX-SONGTIANXI001
*
*/
public interface Human {
/*笑*/
public void laugh();
/*哭*/
public void cry();
/*说话*/
public void talk();
/*性别*/
public void sex();
}
2.定义“白种人”抽象类AbstractWhiteHuman实现了人类接口Human
public abstract class AbstractWhiteHuman implements Human{
/*笑*/
public void laugh() {
System.out.println("白种人笑");
};
/*哭*/
public void cry() {
System.out.println("白种人哭");
};
/*说话*/
public void talk() {
System.out.println("白种人说话");
};
}
3.定义“黄种人”抽象类AbstractYellowHuman实现人类接口Human
public abstract class AbstractYellowHuman implements Human{
/*笑*/
public void laugh() {
System.out.println("白种人笑");
};
/*哭*/
public void cry() {
System.out.println("白种人哭");
};
/*说话*/
public void talk() {
System.out.println("白种人说话");
};
}
3.定义“黑种人”抽象类AbstractBlackHuman实现人类接口Human
public abstract class AbstractBlackHuman implements Human{
/*笑*/
public void laugh() {
System.out.println("白种人笑");
};
/*哭*/
public void cry() {
System.out.println("白种人哭");
};
/*说话*/
public void talk() {
System.out.println("白种人说话");
};
}
(二)具体产品
1.“黄种人”男性
public class YellowMaleHuman extends AbstractYellowHuman{
/*性别*/
public void sex() {
System.out.println("黄种人性别是男的");
};
}
2.“黄种人”女性
public class YellowFemaleHuman extends AbstractYellowHuman{
/*性别*/
public void sex() {
System.out.println("黄种人性别是女的");
};
}
3.“白种人”男性
public class WhiteMaleHuman extends AbstractWhiteHuman{
/*性别*/
public void sex() {
System.out.println("白种人性别是男的");
};
}
4.“白种人”女性
public class WhiteFemaleHuman extends AbstractWhiteHuman{
/*性别*/
public void sex() {
System.out.println("白种人性别是女的");
};
}
5.“黑人”男性
public class BlackMaleHuman extends AbstractBlackHuman{
/*性别*/
public void sex() {
System.out.println("黑种人性别是男的");
};
}
6.“黑人”女性
public class BlackFemaleHuman extends AbstractBlackHuman{
/*性别*/
public void sex() {
System.out.println("黑种人性别是女的");
};
}
(三)抽象工厂
1.定义工厂类接口
/**
* 抽象工厂模式
* @author EX-SONGTIANXI001
*
*/
public interface InterfaceHumanFactory {
// 黄种人
public Human createYellowHuman();
// 白种人
public Human createWhiteHuman();
// 黑种人
public Human createBlackHuman();
}
2.定义工厂抽象类
/**
* 抽象工厂模式
* 抽出公共方法,为了减少实现类中的代码量
* @author EX-SONGTIANXI001
*
*/
public abstract class AbstractHumanFactory implements InterfaceHumanFactory{
public Human createHuman(HumanEnum humanEnum){
Human human = null;
if(!"".equals(humanEnum.getValue())){
try {
human = (Human)Class.forName(humanEnum.getValue()).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return human;
}
}
(四)具体工厂
1.男性工厂
public class MaleHumanFactory extends AbstractHumanFactory{
// 黄种人男性
public Human createYellowHuman(){
return super.createHuman(HumanEnum.YellowMaleHuman);
};
// 白种人男性
public Human createWhiteHuman(){
return super.createHuman(HumanEnum.WhiteMaleHuman);
};
// 黑种人男性
public Human createBlackHuman(){
return super.createHuman(HumanEnum.BlackMaleHuman);
};
public static void main(String[] args){
// 创造男人工厂
InterfaceHumanFactory maleHumanFactory = new MaleHumanFactory();
// 创造了黄种人男性
Human maleYellowHuman = maleHumanFactory.createYellowHuman();
maleYellowHuman.sex();
// 创造了白种人男性
Human maleWhiteHuman = maleHumanFactory.createWhiteHuman();
maleWhiteHuman.sex();
// 创造了黑种人男性
Human maleBlackHuman = maleHumanFactory.createBlackHuman();
maleBlackHuman.sex();
}
}
2.女性工厂
public class FemaleHumanFactory extends AbstractHumanFactory{
//黄种人女性
public Human createYellowHuman(){
return super.createHuman(HumanEnum.YellowFemaleHuman);
};
//白种人女性
public Human createWhiteHuman(){
return super.createHuman(HumanEnum.WhiteFemaleHuman);
};
//黑种人女性
public Human createBlackHuman(){
return super.createHuman(HumanEnum.BlackFemaleHuman);
};
public static void main(String[] args){
// 创造女人工厂
InterfaceHumanFactory femaleHumanFactory = new FemaleHumanFactory();
// 创造了黄种人女性
Human maleYellowHuman = femaleHumanFactory.createYellowHuman();
maleYellowHuman.sex();
// 创造了白种人女性
Human maleWhiteHuman = femaleHumanFactory.createWhiteHuman();
maleWhiteHuman.sex();
// 创造了黑种人女性
Human maleBlackHuman = femaleHumanFactory.createBlackHuman();
maleBlackHuman.sex();
}
}
(五)枚举类
/**
* 为了代码简介美观,便于管理
* @author EX-SONGTIANXI001
*
*/
public enum HumanEnum {
/*定义黄人种*/
YellowFemaleHuman("objectPool.YellowFemaleHuman"),
YellowMaleHuman("objectPool.YellowMaleHuman"),
/*定义白人种*/
WhiteFemaleHuman("objectPool.WhiteFemaleHuman"),
WhiteMaleHuman("objectPool.WhiteMaleHuman"),
/*定义黑人种*/
BlackFemaleHuman("objectPool.BlackFemaleHuman"),
BlackMaleHuman("objectPool.BlackMaleHuman");
private String value = "";
private HumanEnum(String value){
this.value = value;
}
public String getValue(){
return value;
}
}
二、总结
(一)优点
1.降低耦合:抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展。
2.更符合开-闭原则:新增一种产品族时,只需要增加相应的具体产品类和相应的工厂类即可。
(二)缺点
1.抽象工厂模式很难支持新种类产品的变化:
这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开-闭”原则。
PS:产品族和新产品区别以上面例子来说:
1)增加一个“人妖”产品族比较容易只需要新增三个产品实体类性别分别为“黄种人妖”、“白种人妖”、“黑种人妖”(这里没有任何性别歧视0.0),再新增一个生产人妖工厂即可。
2)而如果新增一个“棕色种人”,那么不仅抽象产品和具体产品都需要增加“棕色种人”类外,对于工厂类来说不仅抽象工厂需要修改新增创建“棕色种人”的方法,而且下面的具体工厂都需要修改增加创建“棕色种人”的方法,这样就违背了“开-闭”原则。
3)工厂方法模式新增产品容易新增产品族难,抽象工厂模式与之相反。