《您的设计模式》(CBF4LIFE)之“抽象工厂模式”【整理】
2016-10-27 10:45
453 查看
【实际上加一个抽象类】
上一章,忘记给人类定义性别了,那怎么办?
给每个人类都加一个性别,然后再重新制造。
八卦炉怎么办?
只有一个呀,要么生产出全都是男性,要不都是女性,那不行,有了,把已经有了一条生产线——八卦炉(工厂模式中的Concrete Factory)拆开,于是女娲就使用了“八卦拷贝术”,把原先的八卦炉一个变两个,并且略加修改,就成了女性八卦炉(只生产女性,一个具体工厂的实现类)和男性八卦炉(只生产男性,又一个具体工厂的实现类)
注:抽象工厂只实现了一个createHuman的方法,目的是简化实现类的代码工作量。
定义一个人类总称:
package com.teng.pattern.impl;
/**
* 人类接口
* <br>创建日期:2016年6月22日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public interface Human {
/**
* 哭
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:29:39
*/
public void cry();
/**
* 笑
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:29:54
*/
public void laugh();
/**
* 说
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:30:09
*/
public void talk();
/**
* 性别
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午2:14:08
*/
public void sex();
}
人类的接口定义好,然后根据接口创建三个抽象类,也就是三个产品等级
三个抽象类都实现完毕了,然后就是些实现类了。其实,你说抽象类放这里有什么意义吗?就是不允许你new出来一个抽象的对象。
人类的实现类:
package com.teng.pattern.impl;
/**
* 女性黑种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BlackFemaleHuman extends BlackHuman {
@Override
public void sex() {
System.out.println("女性黑种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性黑种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BlackManHuman extends BlackHuman {
@Override
public void sex() {
System.out.println("男性黑种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 女性白种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class WhiteFemaleHuman extends WhiteHuman {
@Override
public void sex() {
System.out.println("女性白种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性白种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class WhiteManHuman extends WhiteHuman {
@Override
public void sex() {
System.out.println("男性白种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 女性黄种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class YellowFemaleHuman extends YellowHuman {
@Override
public void sex() {
System.out.println("女性黄种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性黄种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class YellowManHuman extends YellowHuman {
@Override
public void sex() {
System.out.println("男性黄种人。。。");
}
}
抽象工厂模式下的产品等级和产品族都已经完成,也就是人类以及产生出的人类是什么样子的都已经定义好了,下一步就等着工厂开工创建了,那我们来看工厂类。
枚举类:
package com.teng.pattern.impl;
/**
* 人类-枚举类
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public enum HumanEnum {
/**
* 女性黑种人
*/
BlackFemaleHuman("com.teng.pattern.impl.BlackFemaleHuman"),
/**
* 男性黑种人
*/
BlackManHuman("com.teng.pattern.impl.BlackManHuman"),
/**
* 女性黄种人
*/
YellowFemaleHuman("com.teng.pattern.impl.YellowFemaleHuman"),
/**
* 男性黄种人
*/
YellowManHuman("com.teng.pattern.impl.YellowManHuman"),
/**
* 女性白种人
*/
WhiteFemaleHuman("com.teng.pattern.impl.WhiteFemaleHuman"),
/**
* 男性白种人
*/
WhiteManHuman("com.teng.pattern.impl.WhiteManHuman");
private String value;
private HumanEnum(String value){
this.value = value;
}
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午2:53:37
*/
public String getValue(){
return this.value;
}
}
getValue()方法,就是获得枚举类型中一个元素的值,枚举类型中的元素也是有名称和值的,这个和HashMap有点类似。
工厂类的接口:
package com.teng.pattern.impl;
/**
* 工厂类接口
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public interface HumanFactory {
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:21
*/
public Human createYellowHuman();
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:28
*/
public Human createWhiteHuman();
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:33
*/
public Human createBlackHuman();
}
抽象工厂类:
package com.teng.pattern.impl;
/**
* 抽象工厂类
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class AbstractHumanFactory implements HumanFactory {
protected Human createHuman(HumanEnum humanEnum) {
Human human = null;
try {
human = (Human)Class.forName(humanEnum.getValue()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return human;
}
}
createHuman(HumanEnum humanEnum)这个方法定义了输入参数必须是HumanEnum类型,然后直接使用humanEnum.getValue()方法就能获得具体传递进来的值。
男性工厂:
package com.teng.pattern.impl;
/**
* 男性工厂
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class ManHumanFactory extends AbstractHumanFactory {
@Override
public Human createYellowHuman() {
return super.createHuman(HumanEnum.YellowManHuman);
}
@Override
public Human createWhiteHuman() {
return super.createHuman(HumanEnum.WhiteManHuman);
}
@Override
public Human createBlackHuman() {
return super.createHuman(HumanEnum.BlackManHuman);
}
}
女性工厂:
开始生产:
工厂模式符合OCP原则,也就是开闭原则,怎么说呢,比如就性别的问题,这个世界上还存在双性人,是男也是女的人,那这个就是要在我们的产品族中增加一类产品,同时再增加一个工厂就可以解决这个问题。
高内聚,低耦合,在一个较大的项目组,产品是由一批人定义开发的,但是提供其他成员访问的时候,只有工厂方法和产品的接口,也就是说只需要提供Product Interface和Concrete Factory就可以产生自己需要的对象和方法,Java的高内聚低耦合的特性表现的一览无遗。
上一章,忘记给人类定义性别了,那怎么办?
给每个人类都加一个性别,然后再重新制造。
八卦炉怎么办?
只有一个呀,要么生产出全都是男性,要不都是女性,那不行,有了,把已经有了一条生产线——八卦炉(工厂模式中的Concrete Factory)拆开,于是女娲就使用了“八卦拷贝术”,把原先的八卦炉一个变两个,并且略加修改,就成了女性八卦炉(只生产女性,一个具体工厂的实现类)和男性八卦炉(只生产男性,又一个具体工厂的实现类)
注:抽象工厂只实现了一个createHuman的方法,目的是简化实现类的代码工作量。
定义一个人类总称:
package com.teng.pattern.impl;
/**
* 人类接口
* <br>创建日期:2016年6月22日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public interface Human {
/**
* 哭
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:29:39
*/
public void cry();
/**
* 笑
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:29:54
*/
public void laugh();
/**
* 说
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月22日 下午10:30:09
*/
public void talk();
/**
* 性别
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午2:14:08
*/
public void sex();
}
人类的接口定义好,然后根据接口创建三个抽象类,也就是三个产品等级
package com.teng.pattern.impl; /** * 黑种人抽象类 * <br>创建日期:2016年6月26日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */ public abstract class BlackHuman implements Human { @Override public void cry() { System.out.println("黑种人哭。。。"); } @Override public void laugh() { System.out.println("黑种人笑。。。"); } @Override public void talk() { System.out.println("黑种人说。。。"); } } package com.teng.pattern.impl; /** * 白种人抽象类 * <br>创建日期:2016年6月26日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */ public abstract class WhiteHuman implements Human { @Override public void cry() { System.out.println("白种人哭。。。"); } @Override public void laugh() { System.out.println("白种人笑。。。"); } @Override public void talk() { System.out.println("白种人说。。。"); } } package com.teng.pattern.impl; /** * 黄种人抽象类 * <br>创建日期:2016年6月26日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */ public abstract class YellowHuman implements Human { @Override public void cry() { System.out.println("黄种人哭。。。"); } @Override public void laugh() { System.out.println("黄种人笑。。。"); } @Override public void talk() { System.out.println("黄种人说。。。"); } }
三个抽象类都实现完毕了,然后就是些实现类了。其实,你说抽象类放这里有什么意义吗?就是不允许你new出来一个抽象的对象。
人类的实现类:
package com.teng.pattern.impl;
/**
* 女性黑种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BlackFemaleHuman extends BlackHuman {
@Override
public void sex() {
System.out.println("女性黑种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性黑种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class BlackManHuman extends BlackHuman {
@Override
public void sex() {
System.out.println("男性黑种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 女性白种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class WhiteFemaleHuman extends WhiteHuman {
@Override
public void sex() {
System.out.println("女性白种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性白种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class WhiteManHuman extends WhiteHuman {
@Override
public void sex() {
System.out.println("男性白种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 女性黄种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class YellowFemaleHuman extends YellowHuman {
@Override
public void sex() {
System.out.println("女性黄种人。。。");
}
}
package com.teng.pattern.impl;
/**
* 男性黄种人
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class YellowManHuman extends YellowHuman {
@Override
public void sex() {
System.out.println("男性黄种人。。。");
}
}
抽象工厂模式下的产品等级和产品族都已经完成,也就是人类以及产生出的人类是什么样子的都已经定义好了,下一步就等着工厂开工创建了,那我们来看工厂类。
枚举类:
package com.teng.pattern.impl;
/**
* 人类-枚举类
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public enum HumanEnum {
/**
* 女性黑种人
*/
BlackFemaleHuman("com.teng.pattern.impl.BlackFemaleHuman"),
/**
* 男性黑种人
*/
BlackManHuman("com.teng.pattern.impl.BlackManHuman"),
/**
* 女性黄种人
*/
YellowFemaleHuman("com.teng.pattern.impl.YellowFemaleHuman"),
/**
* 男性黄种人
*/
YellowManHuman("com.teng.pattern.impl.YellowManHuman"),
/**
* 女性白种人
*/
WhiteFemaleHuman("com.teng.pattern.impl.WhiteFemaleHuman"),
/**
* 男性白种人
*/
WhiteManHuman("com.teng.pattern.impl.WhiteManHuman");
private String value;
private HumanEnum(String value){
this.value = value;
}
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午2:53:37
*/
public String getValue(){
return this.value;
}
}
getValue()方法,就是获得枚举类型中一个元素的值,枚举类型中的元素也是有名称和值的,这个和HashMap有点类似。
工厂类的接口:
package com.teng.pattern.impl;
/**
* 工厂类接口
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public interface HumanFactory {
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:21
*/
public Human createYellowHuman();
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:28
*/
public Human createWhiteHuman();
/**
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年6月26日 下午3:06:33
*/
public Human createBlackHuman();
}
抽象工厂类:
package com.teng.pattern.impl;
/**
* 抽象工厂类
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class AbstractHumanFactory implements HumanFactory {
protected Human createHuman(HumanEnum humanEnum) {
Human human = null;
try {
human = (Human)Class.forName(humanEnum.getValue()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return human;
}
}
createHuman(HumanEnum humanEnum)这个方法定义了输入参数必须是HumanEnum类型,然后直接使用humanEnum.getValue()方法就能获得具体传递进来的值。
男性工厂:
package com.teng.pattern.impl;
/**
* 男性工厂
* <br>创建日期:2016年6月26日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class ManHumanFactory extends AbstractHumanFactory {
@Override
public Human createYellowHuman() {
return super.createHuman(HumanEnum.YellowManHuman);
}
@Override
public Human createWhiteHuman() {
return super.createHuman(HumanEnum.WhiteManHuman);
}
@Override
public Human createBlackHuman() {
return super.createHuman(HumanEnum.BlackManHuman);
}
}
女性工厂:
package com.teng.pattern.impl; /** * 女性工厂 * <br>创建日期:2016年6月26日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */ public class FemaleHumanFactory extends AbstractHumanFactory { @Override public Human createYellowHuman() { return super.createHuman(HumanEnum.YellowFemaleHuman); } @Override public Human createWhiteHuman() { return super.createHuman(HumanEnum.WhiteFemaleHuman); } @Override public Human createBlackHuman() { return super.createHuman(HumanEnum.BlackFemaleHuman); } }
开始生产:
package com.teng.pattern; import com.teng.pattern.impl.FemaleHumanFactory; import com.teng.pattern.impl.Human; import com.teng.pattern.impl.ManHumanFactory; /** * 造物主 * <br>创建日期:2016年6月22日 * <br><b>Copyright 2016 tengxiang All Rights Reserved</b> * @author tengxiang * @since 1.0 * @version 1.0 */ public class God { /** * 主方法 * @since 1.0 * @param args * <br><b>作者: @author tengxiang</b> * <br>创建时间:2016年6月22日 下午10:55:37 */ public static void main(String[] args){ FemaleHumanFactory femaleHumanFactory = new FemaleHumanFactory(); ManHumanFactory manHumanFactory = new ManHumanFactory(); Human blackFemaleHuman = femaleHumanFactory.createBlackHuman(); blackFemaleHuman.cry(); blackFemaleHuman.sex(); Human blackManHuman= manHumanFactory.createBlackHuman(); blackManHuman.cry(); blackManHuman.sex(); //...... } }
工厂模式符合OCP原则,也就是开闭原则,怎么说呢,比如就性别的问题,这个世界上还存在双性人,是男也是女的人,那这个就是要在我们的产品族中增加一类产品,同时再增加一个工厂就可以解决这个问题。
高内聚,低耦合,在一个较大的项目组,产品是由一批人定义开发的,但是提供其他成员访问的时候,只有工厂方法和产品的接口,也就是说只需要提供Product Interface和Concrete Factory就可以产生自己需要的对象和方法,Java的高内聚低耦合的特性表现的一览无遗。
相关文章推荐
- 《您的设计模式》(CBF4LIFE)之“代理模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“模板方法模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“装饰模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“单例模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“策略模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“门面模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“命令模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“责任链模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“建造者模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“工厂方法模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“适配器模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“桥梁模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“多例模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“组合模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“状态模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“迭代器模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“访问者模式”【整理】
- 《您的设计模式》(CBF4LIFE)之“观察者模式”【整理】
- [设计模式整理笔记 四] 抽象工厂模式(Abstract Factory)
- 收藏别人整理的 设计模式(设计模式(3): 抽象工厂模式 )