java23种常用设计模式之抽象工厂模式(Abstract Factory)2

来源:互联网 发布:项目参数估算法 编辑:程序博客网 时间:2024/06/02 03:04

继续上一篇的工厂方法模式的优化,上一节讲到一个例子,生产白人、黑人和黄人,会说会笑,但是人有男有女,这个怎么拓展呢?重新生产一次?太不理智了!

之前花费了那么多功夫,不能白忙一场呀!

这里我们引入一个抽象工厂,问题就简单了!抽象工厂只实现了一个createHuman 的方法,目的是简化实现类的代码工作量,这个在讲代码的时候再说。这里还使用了Jdk 1.5以上版本 的一个新特性Enum 类型,其实这个完全可以由类的静态变量来实现,但我想既然是学习就应该学有所获得,学以致用,即使你对这个模式非常了解,也可能没用过Enum 类型,也算是一个不同以往的知识点吧,我希望给大家讲解,每次都有新的技术点提出来,每个人都会有一点的新的收获,然后在具体的项目中使用时,知道有这个技术点,然后上baidu Google一下就能解决问题。(话题扯远了……)上代码……

Human不是那个Human啦,我有男女之分……

package com.freedom.factory.abstractfactory;public interface Human2 {        public void say();    public void smile();    //性别    public void gender();}
定义三个抽象人种(抽象类)
package com.freedom.factory.abstractfactory;import com.freedom.factory.factory2.Human;public abstract class AbstractWhiteHuman implements Human{@Overridepublic void say() {System.out.println("white human can say anything!");}@Overridepublic void smile() {System.out.println("white human can smile!");}}package com.freedom.factory.abstractfactory;import com.freedom.factory.factory2.Human;public abstract class AbstractBlackHuman implements Human{            @Override    public void say() {        System.out.println("black human can say anything!");            }    @Override    public void smile() {        System.out.println("black human can smile!");            }}package com.freedom.factory.abstractfactory;import com.freedom.factory.factory2.Human;public abstract class AbstractYellowHuman implements Human{            @Override    public void say() {        System.out.println("yellow human can say anything!");            }    @Override    public void smile() {        System.out.println("yellow human can smile!");            }}
由于以上人种都是抽象类,java是不允许你new出一个人来的,之恩能够乖乖实现它,这下就好玩了,你想实现一个female还是一个male呢!随便了!(粤语:shi dan la!)

package com.freedom.factory.abstractfactory;public class YellowFemaleHuman extends AbstractWhiteHuman{@Overridepublic void gender() {System.out.println("Yellow Lady first!");}}package com.freedom.factory.abstractfactory;public class YellowMaleHuman extends AbstractWhiteHuman{    @Override    public void gender() {        System.out.println("Yellow Male!");            }    }//黑人和白人的代码大家自己写吧!我不贴了,我有空上传了代码就吧链接补上。
这里我引入了枚举类型,有兴趣可以看看。Enum 以前我也很少用,最近在一个项目中偶然使用上了,然后才发觉它的好处,Enum 类型作为一个参数传递到一个方法中时,在Junit 进行单元测试的时候,不用判断输入参数是否为空、长度为0 的边界异常条件,如果方法传入的参数不是Enum 类型的话,根本就传递不进来,你说定义一个类,定义一堆的静态变量,这也可以呀,这个不和你抬杠,下面的代码我解释一下,构造函数没啥好说的,然后是getValue()方法,就是获得枚举类型中一个元素的值,枚举类型中的元素也是有名称和值的,这个和HashMap 有点类似。

package com.freedom.factory.abstractfactory;public enum HumanEnum {// 把世界上所有人类型都定义出来YelloMaleHuman("com.freedom.factory.abstractfactory.YellowMaleHuman"), YelloFemaleHuman("com.freedom.factory.abstractfactory.YellowFemaleHuman"), WhiteFemaleHuman("com.freedom.factory.abstractfactory.WhiteFemaleHuman"), WhiteMaleHuman("com.freedom.factory.abstractfactory.WhiteMaleHuman"), BlackFemaleHuman("com.freedom.factory.abstractfactoryBlackFemaleHuman"), BlackMaleHuman("com.freedom.factory.abstractfactory.BlackMaleHuman");private String value = "";// 定义构造函数,目的是Data(value)类型的相匹配private HumanEnum(String value) {this.value = value;}public String getValue() {return this.value;}/* * java enum类型尽量简单使用,尽量不要使用多态、继承等方法 毕竟用Class完全可以代替enum */}
然后,我们看我们的工厂类,先看接口:

package com.freedom.factory.abstractfactory;import com.freedom.factory.factory2.Human;public interface HumanFactory {//制造黄色人种public Human createYellowHuman();//制造一个白色人种public Human createWhiteHuman();//制造一个黑色人种public Human createBlackHuman();}
然后看抽象类:

package com.freedom.factory.abstractfactory;public abstract class AbstractHumanFactory implements HumanFactory {/* * 给定一个性别人种,创建一个人类出来专业术语是产生产品等级 */protected Human2 createHuman(HumanEnum HumanEnum) {Human2 human = null;// 如果传递进来不是一个Enum中具体的一个Element的话,则不处理if (!HumanEnum.getValue().equals("")) {try {// 直接产生一个实例human = (Human2) Class.forName(HumanEnum.getValue()).newInstance();} catch (Exception e) {// 因为使用了enum,这个种异常情况不会产生了,除非你的enum有问题;e.printStackTrace();}}return human;}}/*看到没,这就是引入enum 的好处,createHuman(HumanEnum humanEnum)这个方法定义了输入参数必须是HumanEnum 类型,然后直接使用humanEnum.getValue()方法就能获得具体传递进来的值,这个不多说了,大家自己看程序领会,没多大难度,这个抽象类的目的就是减少下边实现类的代码量.*/ 
female工厂

package com.freedom.factory.abstractfactory;public class FemaleHumanFactory extends AbstractHumanFactory {// 创建一个女性黑种人public Human2 createBlackHuman() {return super.createHuman(HumanEnum.BlackFemaleHuman);}// 创建一个女性白种人public Human2 createWhiteHuman() {return super.createHuman(HumanEnum.WhiteFemaleHuman);}// 创建一个女性黄种人public Human2 createYellowHuman() {return super.createHuman(HumanEnum.YelloFemaleHuman);}}
male工厂

package com.freedom.factory.abstractfactory;public class MaleHumanFactory extends AbstractHumanFactory {// 创建一个男性黑种人public Human2 createBlackHuman() {return super.createHuman(HumanEnum.BlackMaleHuman);}// 创建一个男性白种人public Human2 createWhiteHuman() {return super.createHuman(HumanEnum.WhiteMaleHuman);}// 创建一个男性黄种人public Human2 createYellowHuman() {return super.createHuman(HumanEnum.YelloMaleHuman);}}
test

package com.freedom.factory.abstractfactory;import org.junit.Test;public class TestAbstractFactory {@Testpublic void test3() {//第一条生产线,男性生产线HumanFactory maleHumanFactory = new MaleHumanFactory();//第二条生产线,女性生产线HumanFactory femaleHumanFactory = new FemaleHumanFactory();//生产线建立完毕,开始生产人了:Human2 maleYellowHuman = maleHumanFactory.createYellowHuman();Human2 femaleYellowHuman = femaleHumanFactory.createYellowHuman();maleYellowHuman.say();maleYellowHuman.smile();femaleYellowHuman.gender();/** .....* 后面shi dan (随便)你了!*/}}

抽象工厂模式讲完了,我们再思考一些问题:工厂模式有哪些优缺点?

小结一下,先说优点,我这人一般先看人优点,非常重要的一点是,工厂模式符合OCP (开闭原则),怎么说呢,比如就性别的问题,这个世界上还存在双性人(for example泰国人妖),是男的也是女的,那这个就是要再增加一个工厂(FemaleAndMaleFactory)就可以解决这个问题,我就不写了,很简单的!大家自己有兴趣可以画下类图,然后实现下,也相当于温故,然后看看能不能知新。
那还有没有其他好处呢?抽象工厂模式,有一个非常大的有点,高内聚,低耦合,在一个较大的项目组,产品是由一批人定义开发的,但是提供其他成员访问的时候,只有工厂方法和产品的接口,也就是说只需要提供Product Interface 和Concrete Factory 就可以产生自己需要的对象和方法,Java 的高内聚低耦合的特性表现的一览无遗,哈哈,终于Over了!


下载源码:http://download.csdn.net/detail/github_22022001/8290541

0 0
原创粉丝点击