用女蜗造人阐述工厂模式
1.1 一个工厂模式
现在女娲要造人,她要造三种人:白种人、黄种人和黑种人。怎么造呢?她得有个能产生人类的工厂吧(类似于八卦炉的东西),这个工厂得让她生产出不同的人种。每个人都有两个属性:皮肤颜色和说话
抽象接口Human是人类,里面有两个方法,getColor获得皮肤颜色,talk交谈。下面三个具体Human的实现类,分别实现三个人种。根据工厂模式,应该有个抽象工厂,AbstractHumanFactory就担当了这个责任,里面有个抽象方法createHuman,那HumanFactory就是实现类了,实现抽象工厂里的方法。下面我们看看具体实现:
public interface Human { public void getColor();//人有不同的颜色 public void talk(); //人会说话
}
接下来对Human接口的不同实现:
public class BlackHuman implements Human {// 黑种人@Overridepublic void getColor() {System.out.println("Black");}@Overridepublic void talk() {System.out.println("Black man");}
}
public class Human implements Human { //黄种人@Overridepublic void getColor() {System.out.println("Yellow");}@Overridepublic void talk() {System.out.println("Yellow man");}
}
public class WhiteHuman implements Human {//白种人@Overridepublic void getColor() {System.out.println("White");}@Overridepublic void talk() {System.out.println("White man");}
}
好了,人的模子搞好了,现在女娲要开始搭建八卦炉了:
public abstract class AbstractHumanFactory{public abstract <T extends Human> T createHuman(Class<T> clazz); //注意这里T必须是Human的实现类才行,因为要造Human嘛
}
public class HumanFactory extends AbstractHumanFactory {@Overridepublic <T extends Human> T createHuman(Class<T> clazz) {Human human = null;try {human = (Human) Class.forName(clazz.getName()).newInstance();} catch (Exception e) { //异常处理System.out.println("人种产生错误");}return (T) human;}
}
public class FactoryTest {public static void main(String[] args) {AbstractHumanFactory bagualu = new HunmanFactory();Human blackMan = bagualu.createHuman(BlackHuman.class); //黑人诞生了Human yellowMan = bagualu.createHuman(YelloHuman.class); //黄人诞生了Human whiteMan = bagualu.createHuman(WhiteHuman.class); //白人诞生了}
}
这就是工厂模式!
1.2 静态工厂模式
我们还用上面女娲造人的例子说明,现在女娲在思考一个问题:我现在只需要一个工厂就可以把人生产出来,我干嘛要具体的工厂对象呢?我只要使用静态方法就好了。这样一想,于是女娲就开始把AbstractHumanFactory抽象类去掉了,只保留了HumanFactory类,同时把createHuman方法设置成了static类型,搞定!
public class HumanFactory {public static <T extends Human> T createHuman(Class<T> clazz) {Human human = null;try {human = (Product) Class.forName(clazz.getName()).newInstance();} catch (Exception e) { //异常处理System.out.println("人种产生错误");}return (T) human;}
}
这就是静态工厂模式,在实际项目中,根据需求可以设置成静态工厂类,但是缺点是扩展比较困难,如果就一个工厂,不需要扩展,可以这么设计,仍然是很常用的。
1.3 多个工厂模式
abstractHumanFactory抽象类我们就要改写:
public abstract class AbstractHumanFactory {public abstract Human createHuman();
}
public class BlackHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new BlackHuman();}
}
public class YellowHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new YellowHuman();}
}
public class WhiteHumanFactory extends AbstractHumanFactory {public Human createHuman() {return new WhiteHuman();}
}
public class FactoryTest {public static void main(String[] args) {Human blackMan = new BlackHumanFactory().createHuman(); //黑人诞生了Human yellowMan = new YellowHumanFactory().createHuman(); //黄人诞生了Human whiteMan = new WhiteHumanFactory().createHuman(); //白人诞生了}
}
这种工厂模式的好处是职责清晰,结构简单,但是给扩扩展性和可维护性带来了一定的影响,因为如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难度。因为工厂类和产品类的数量是相同的,维护时也需要考虑两个对象之间的关系。但是这种模式还是很常用的。