您的位置:首页 > Web前端

《您的设计模式》(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();
}
人类的接口定义好,然后根据接口创建三个抽象类,也就是三个产品等级

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的高内聚低耦合的特性表现的一览无遗。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式 java