突然有一天,在梦里拥有了阿拉丁神灯。
灯神说: "我可以给你创造一个女朋友哦"
"但是只能满足你一个地理条件,目前只有三个选项: 四川, 河北, 山东. 你挑一个? " 灯神又说。
"那我选: 四川...或者..."
没等我说完,嘭的一下,出来个一个火辣的川妹子...
简单工厂模式
首先创建妹子的类型,四川, 河北, 山东。用枚举来表示:
public enum GirlFriendType {
SI_CHUAN,
HE_BEI,
SHAN_DONG
}
然后再看看要和妹子干什么,比如购物和吃东西,购物是一定的了,吃东西则由每个地方的口味决定,所以创建一个抽象类:
public abstract class BaseGirlFriend {
public abstract void eatFood();
public void shopping() {
System.out.println("天天都要购物");
}
}
然后创建三个地区的妹子实现类:
//四川妹子
public class SiChuangGirlFriend extends BaseGirlFriend {
@Override
public void eatFood() {
Log.i("BaseGirlFriend", "吃四川辣椒。");
}
}
//河北妹子
public class HeBeiGirlFriend extends BaseGirlFriend {
@Override
public void eatFood() {
Log.i("BaseGirlFriend", "吃河北食物。");
}
}
//山东妹子
public class ShanDongGirlFriend extends BaseGirlFriend {
@Override
public void eatFood() {
Log.i("BaseGirlFriend", "吃山东包子。");
}
}
最后创建一个工厂来创建妹子,默认是河北的吧:
public class GirlFriendFactory {
public static BaseGirlFriend createGirlFriend(GirlFriendType type) {
switch (type) {
case SI_CHUAN:
return new SiChuangGirlFriend();
case SHAN_DONG:
return new ShanDongGirlFriend();
case HE_BEI:
return new HeBeiGirlFriend();
default:
return new HeBeiGirlFriend();
}
}
}
然后,在用的时候是这样的:
//选择了山东妹子一起吃饭购物
BaseGirlFriend shandong = GirlFriendFactory.createGirlFriend(GirlFriendType.SHAN_DONG);
shandong.eatFood();
shandong.shopping();
//选择了四川妹子一起吃饭购物
BaseGirlFriend sichuan = GirlFriendFactory.createGirlFriend(GirlFriendType.SI_CHUAN);
sichuan.eatFood();
sichuan.shopping();
//选择了河北妹子一起吃饭购物
BaseGirlFriend hebei = GirlFriendFactory.createGirlFriend(GirlFriendType.HE_BEI);
hebei.eatFood();
hebei.shopping();
然后可以看出,这种简单工厂模式是有缺陷的,比如我现在不选这三个地区的了,我要选择云南的妹子,那么我就需要修改枚举类代码,修改工厂类代码,非常麻烦。
那么,是否可以通过一个接口,让我喜欢选哪个地方就选哪个地方?
工厂模式
首先创建一个接口:
public interface IGirlFriendFactory {
BaseGirlFriend createGirlFriend();
}
然后为每个地方的妹子都建一个工厂,并实现这个接口(河北为例,其他地方一样):
public class HeBeiGirlFriendFactory implements IGirlFriendFactory {
@Override
public BaseGirlFriend createGirlFriend() {
return new HeBeiGirlFriend();
}
}
然后其他类跟之前一样,然后在用的时候是这样的:
IGirlFriendFactory hebeiFactory = new HeBeiGirlFriendFactory();
BaseGirlFriend hebei = hebeiFactory.createGirlFriend();
hebei.shopping();
hebei.eatFood();
可以看到,想实现哪个地方的妹子,只需要继承 IGirlFriendFactory 接口就可以了,代码也不需要修改。
有时候也可以利用反射方式更加简洁地来生产具体对象,需要在工厂方法的参数列表中传入一个Class类来决定哪一个产品类:
修改 IGirlFriendFactory 工厂接口为:
public interface IGirlFriendFactory {
<T extends BaseGirlFriend> T createGirlFriend(Class<T> clz);
IGirlFriendFather createGirlFriendFather();
}
然后具体的工厂实现类:
public class GirlFriendFactory implements IGirlFriendFactory {
@Override
public <T extends BaseGirlFriend> T createGirlFriend(Class<T> clz) {
BaseGirlFriend baseGirlFriend = null;
try {
baseGirlFriend = (BaseGirlFriend) Class.forName(clz.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return (T) baseGirlFriend;
}
@Override
public IGirlFriendFather createGirlFriendFather() {
return new HeBeiGirlFriendFather();
}
}
最后在使用的时候这样,看着是不是简洁很多:
IGirlFriendFactory factory = new GirlFriendFactory();
BaseGirlFriend hebei = factory.createGirlFriend(HeBeiGirlFriend.class);
hebei.shopping();
hebei.eatFood();
好多年以后,发现妹子的父母还没见啊,不知道父母同不同意。然后我们去找神灯大哥帮忙。
抽象工厂模式
创建妹子父母接口,以父亲为例:
public interface IGirlFriendFather {
// 对于闺女和我的事情的建议
void suggestionToGirl();
}
然后实现这个接口(同意或不同意或其他),以河北妹子为例:
public class HeBeiGirlFriendFather implements IGirlFriendFather {
@Override
public void suggestionToGirl() {
Log.i("BaseGirlFriend", "我同意了。");
}
}
然后再工厂接口里面增加一个创建妹子父亲的方法:
public interface IGirlFriendFactory {
BaseGirlFriend createGirlFriend();
IGirlFriendFather createGirlFriendFather();
}
所以河北妹子实现类:
public class HeBeiGirlFriendFactory implements IGirlFriendFactory {
@Override
public BaseGirlFriend createGirlFriend() {
return new HeBeiGirlFriend();
}
@Override
public IGirlFriendFather createGirlFriendFather() {
return new HeBeiGirlFriendFather();
}
}
最后在用的时候,通过工厂创建妹子的父亲,并调用方法发表意见:
IGirlFriendFactory hebeiFactory = new HeBeiGirlFriendFactory();
BaseGirlFriend hebei = hebeiFactory.createGirlFriend();
hebei.shopping();
hebei.eatFood();
//创建妹子父亲
IGirlFriendFather hebeiFather = hebeiFactory.createGirlFriendFather();
hebeiFather.suggestionToGirl();
参考自
ocoaChinabbs
《Android源码设计模式解析与实践》