《您的设计模式》(CBF4LIFE)之“抽象工厂模式”【整理】

来源:互联网 发布:纯实木床品牌 知乎 编辑:程序博客网 时间:2024/06/01 15:31

【实际上加一个抽象类】

上一章,忘记给人类定义性别了,那怎么办?

每个人类都加一个性别,然后再重新制造

八卦炉办?

只有一个呀,要么生产出全都是男性,要不都是女性,那不行,有了,已经有了一条生产线——八卦炉(工厂模式中的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 {@Overridepublic void cry() {System.out.println("黑种人哭。。。");}@Overridepublic void laugh() {System.out.println("黑种人笑。。。");}@Overridepublic 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 {@Overridepublic void cry() {System.out.println("白种人哭。。。");}@Overridepublic void laugh() {System.out.println("白种人笑。。。");}@Overridepublic 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 {@Overridepublic void cry() {System.out.println("黄种人哭。。。");}@Overridepublic void laugh() {System.out.println("黄种人笑。。。");}@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic Human createYellowHuman() {return super.createHuman(HumanEnum.YellowManHuman);}@Overridepublic Human createWhiteHuman() {return super.createHuman(HumanEnum.WhiteManHuman);}@Overridepublic 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 {@Overridepublic Human createYellowHuman() {returnsuper.createHuman(HumanEnum.YellowFemaleHuman);}@Overridepublic Human createWhiteHuman() {returnsuper.createHuman(HumanEnum.WhiteFemaleHuman);}@Overridepublic Human createBlackHuman() {returnsuper.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 InterfaceConcrete Factory可以产生自己需要的对象和方法,Java的高内聚低耦合的特性表现的一览无遗。





0 0
原创粉丝点击