设计模式-抽象工厂模式

上一次女娲造人忘记给人类定义性别了。
现在需要把八卦炉拆开,一个生产男性的八卦炉,一个是生产女性的八卦炉
这里写图片描述

/**
 * Created by xpeng on 2018/5/1.
 * 定义一个人类的统称
 */

public interface Human {
    //首先定义什么是人类

    //人是会笑的
    public void laugh();

    //人类还会哭
    public void cry();

    //人类会说话
    public void talk();

    //定义性别
    public void sex();
}

人类的接口定义好,然后根据接口创建三个抽象类,也就是三个产品等级,实现laugh()、cry()、talk()三个方法

/**
 * Created by xpeng on 2018/5/5.
 * 为什么要修改成抽象类呢?要定义性别啊
 */

public abstract class AbstractYellowHuman implements Human {
    @Override
    public void cry() {
        Log.e("xyz","黄色人类会哭");
    }

    @Override
    public void talk() {

        Log.e("xyz","黄色人类会说话");
    }

    @Override
    public void laugh() {
        Log.e("xyz","黄色人类会笑");
    }

}
public abstract class AbstractWhiteHuman implements Human {
    @Override
    public void cry() {
        Log.e("xyz","白色人类会哭");
    }

    @Override
    public void talk() {
        Log.e("xyz","白色人类会说话");
    }

    @Override
    public void laugh() {
        Log.e("xyz","白色人类会笑");
    }

}
/**
 * Created by xpeng on 2018/5/5.
 */

public abstract class AbstractBlackHuman implements Human {
    @Override
    public void cry() {
        Log.e("xyz","黑色人类会哭");
    }

    @Override
    public void talk() {
        Log.e("xyz","黑色人类会说话");
    }

    @Override
    public void laugh() {
        Log.e("xyz","黑色人类会笑");
    }

}

三个抽象类都实现完毕了,然后就是具体实现类了。

/**
 * Created by xpeng on 2018/5/1.
 * 女性黄色人类
 */

public class YellowFemaleHuman extends AbstractYellowHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 女性黄色人 ");
    }
}
/**
 * Created by xpeng on 2018/5/1.
 * 男性黄色人类
 */

public class YellowMaleHuman extends AbstractYellowHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 男性黄色人 ");
    }
}
/**
 * Created by xpeng on 2018/5/1.
 * 女性白色人类
 */

public class WhiteFemaleHuman extends AbstractWhiteHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 女性白色人 ");
    }
}
/**
 * Created by xpeng on 2018/5/1.
 * 男性白色人类
 */

public class WhiteMaleHuman extends AbstractWhiteHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 男性白色人 ");
    }
}
/**
 * Created by xpeng on 2018/5/1.
 * 女性黑色人类
 */

public class BlackFemaleHuman extends AbstractBlackHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 女性黑色人 ");
    }
}
/**lack
 * Created by xpeng on 2018/5/1.
 * 男性黑色人类
 */

public class BlackMaleHuman extends AbstractBlackHuman {
    @Override
    public void sex() {
        Log.e("xyz"," 男性黑色人 ");
    }
}

抽象工厂模式下的产品等级和产品族都已经完成,也就是人类以及产生出的人类是什么样子的都已经定义好了,下一步就等着工厂开工创建了,接着创建工厂类

/**
 * Created by xpeng on 2018/5/5.
 * 世界上有哪些类型的人,列出来
 */

public enum HumanEnum {

    YelloMaleHuman("com.example.xpeng.mode.YellowMaleHuman"),
    YelloFemalHuman("com.example.xpeng.mode.YellowFemaleHuman"),
    WhiteFemalHuman("com.example.xpeng.mode.WhiteFemaleHuman"),
    WhiteMaleHuman("com.example.xpeng.mode.WhiteMaleHuman"),
    BlackMaleHuman("com.example.xpeng.mode.BlackMaleHuman"),
    BlackFemalHuman("com.example.xpeng.mode.BlackFemaleHuman");

    private String value = "";

    //定义构造函数,目的是Data(value)类型的相匹配
    private HumanEnum(String value){
        this.value = value;
    }

    public String getValue(){
        return this.value;
    }

}

工厂类,先看接口:

/**
 * Created by xpeng on 2018/5/1.
 * 女娲八卦炉造人
 */

public interface HumanFactory {

   //制造黄色人类
    public Human createYellowHuman();

    //制造一个白色人类
    public Human createWhiteHuman();

    //制造一个黑色人类
    public Human createBlackHuman();

}

然后看抽象类:

/**
 * Created by xpeng on 2018/5/5.
 * 编写一个抽象类,根据enum创建一个类出来
 */

public abstract class AbstractHumanFactory implements HumanFactory {
    //给定一个性别人类,创建一个人类出来,专业术语是产生产品等级
    protected Human createHuman(HumanEnum humanEnum){
        Human human = null;

        //如果传递进来不是一个Enum中具体的一个Element的话,则不处理
        if (!humanEnum.getValue().equals("")){
            try {
                //直接生产一个实例
                human = (Human) Class.forName(humanEnum.getValue()).newInstance();
            }catch (Exception e){
                //因为使用了enum,这个异常情况不会产生了,除非你的enum有问题;
                e.printStackTrace();
            }
        }
        return human;
    }
}

这里就是引入enum的好处,createHuman(HumanEnum humanEnum)这个方法定义了输入参数必须是HumanEnum类型,然后直接使用humanEnum.getValue()方法就能获得具体传递进来的值。抽象类的目的就是减少下面实现类的代码量
接下来实现类
男性工厂,只创建男性:

/**
 * Created by xpeng on 2018/5/5.
 * 男性创建工厂
 */

public class MaleHumanFactory extends AbstractHumanFactory {

    //创建一个男性黑种人
    @Override
    public Human createYellowHuman() {
        return super.createHuman(HumanEnum.BlackMaleHuman);
    }

    //创建一个男性白种人
    @Override
    public Human createWhiteHuman() {
        return super.createHuman(HumanEnum.WhiteMaleHuman);
    }

    //创建一个男性黄种人
    @Override
    public Human createBlackHuman() {
        return super.createHuman(HumanEnum.YelloMaleHuman);
    }
}

女性工厂,只创建女性;

/**
 * Created by xpeng on 2018/5/5.
 * 男性创建工厂
 */

public class FemaleHumanFactory extends AbstractHumanFactory {

    //创建一个男性黑种人
    @Override
    public Human createYellowHuman() {
        return super.createHuman(HumanEnum.YelloFemalHuman);
    }

    //创建一个男性白种人
    @Override
    public Human createWhiteHuman() {
        return super.createHuman(HumanEnum.WhiteFemalHuman);
    }

    //创建一个男性黄种人
    @Override
    public Human createBlackHuman() {
        return super.createHuman(HumanEnum.BlackFemalHuman);
    }
}

好咯,都定义好了,接下来就是造人咯

  //第一条生产线,男性生产线
        HumanFactory maleHumanFactory = new MaleHumanFactory();

        //第二条生产线,女性生产线
        HumanFactory femalHumanFactory = new FemaleHumanFactory();

        //生产线建立完毕,开始生产人了
        Human maleYellowHuman = maleHumanFactory.createYellowHuman();

        Human femalYellowHuman = femalHumanFactory.createYellowHuman();

        maleYellowHuman.cry();
        Log.e("xyz"," maleYellow   ... cry ");
        maleYellowHuman.laugh();
        maleYellowHuman.talk();
        femalYellowHuman.sex();
        Log.e("xyz","  femalYellowHuman ... sex ");
        maleYellowHuman.sex();
        //......还可以创建很多,只要你愿意
    }

抽象工厂模式讲完了,工厂模式有哪些优点呢?
1.符合OCP原则,开闭原则。可扩展
2.高内聚,低耦合

猜你喜欢

转载自blog.csdn.net/qq_20967339/article/details/80210706