
1.把创建对象交给工厂去实现,自己不管创建过程,由工厂负责创建过程。
2.业务背景
女娲造人,用泥土捏成人形,在炉子里烤,没烤熟的是白人,烤过头的是黑人,火候刚好的是黄种人。
3.定义人类接口
public interface Human {
//人是愉快的,会笑的;
public void laugh();
// 人类还会哭,代表痛苦
public void cry();
// 人类会说话
public void talk();
}
4.定义具体的人类
// 黄种人
public class YellowHuman implements Human {
public void cry() {System.out.println("黄色人类会哭" );}
public void laugh() {System.out.println("黄色人类会大笑,幸福呀!" );}
public void talk() {System.out.println("黄色人类会说话,一般说的都是双字节" );}
}
// 白人
public class WhiteHuman implements Human {
public void cry() {System.out.println("白色人类会哭" );}
public void laugh() {System.out.println("白色人类会大笑,侵略的笑声" );}
public void talk() {System.out.println("白色人类会说话,一般都是但是单字节!" ); }
}
//黑人
public class BlackHuman implements Human {
public void cry() {System.out.println("黑人会哭" );}
public void laugh() {System.out.println("黑人会笑" );}
public void talk() {System.out.println("黑人可以说话,一般人听不懂" ); }
}
5.定义烤炉
public class HumanFactory {
// 定一个烤箱,泥巴塞进去,人就出来
public static Human createHuman(Class c){
Human human=null; // 定义一个类型的人类
try {
human = (Human)Class.forName(c.getName()).newInstance(); // 产生一个 人类
} catch (InstantiationException e) {
// 你要是不说个人类颜色的话,没法烤,要白的 黑,你说话了才好烤
System.out.println("必须指定人类的颜色" );
} catch (IllegalAccessException e) {
//定义的人类有问题,那就烤不出来了
System.out.println("人类定义错误!" );
} catch (ClassNotFoundException e) {
// 你随便说个人类,我到哪里给你制造去?
System.out.println("混蛋,你指定的人类找不到!" );
}
return human;
}
}
6.定义女娲
public class NvWa {
public static void main(String[] args) {
// 女娲第一次造人,试验性质,少造点,火候不足,缺陷产品
System.out.println("------------ 造出的第一批人是这样的:白人-----------------" );
Human whiteHuman = HumanFactory.createHuman(WhiteHuman.class );
whiteHuman.cry();
whiteHuman.laugh();
whiteHuman.talk();
// 女娲第二次造人,火候加足点,黑人
System.out.println("\n\n------------ 造出的第二批人是这样的:黑人-----------------" );
Human blackHuman = HumanFactory.createHuman(BlackHuman.class );
blackHuman.cry();
blackHuman.laugh();
blackHuman.talk();
//第三批人了,这次火候掌握的正好,黄色人类
System.out.println("\n\n------------ 造出的第三批人是这样的:黄色人类-----------------" );
Human yellowHuman = HumanFactory.createHuman(YellowHuman.class );
yellowHuman.cry();
yellowHuman.laugh();
yellowHuman.talk()
}
}
7.女娲不想一个个造人,想直接把泥巴丢到炉子里,出来什么人就是什么人

修改HumanFactory.java,增加了 createHuman()方法
public class HumanFactory {
// 定一个烤箱,泥巴塞进去,人就出来,这个太先进了
public static Human createHuman(Classc){
Human human=null; // 定义一个类型的人类
try {human = (Human)Class.forName(c.getName()).newInstance(); // 产生一个人类
} catch (InstantiationException e) {
// 你要是不说个人类颜色的话,没法烤,要白的 黑,你说话了才好烤
System.out.println("必须指定人类的颜色" );
} catch (IllegalAccessException e) {
//定义的人类有问题,那就烤不出来了
System.out.println("人类定义错误!" );
} catch (ClassNotFoundException e) {
// 你随便说个人类,我到哪里给你制造去?!
System.out.println("混蛋,你指定的人类找不到!" );
}
return human;
}
// 女娲生气了,把一团泥巴塞到八卦炉,哎产生啥人类就啥人类
public static Human createHuman(){
Human human=null; // 定义一个类型的人类
// 首先是获得有多少个实现类,多少个人类
List<Class> concreteHumanList = ClassUtils.getAllClassByInterface(Human.class); // 定义了多少人类
// 八卦炉自己开始想烧出什么人就什么人
Random random = new Random();
int rand = random.nextInt(concreteHumanList.size());
human = createHuman(concreteHumanList.get(rand));
return human;
}
}
8.工厂方法模式还有一个非常重要的应用,就是延迟始化(Lazy initialization),什么是延迟始化呢? 一个对象初始化完毕后就不释放,等到再次用到得就不用再次初始化了,直接从内存过中拿到就可以了
public class HumanFactory {
//定义一个MAP,初始化过的Human 对象都放在这里
private static HashMap<String,Human> humans = new HashMap<String,Human>();
// 定一个烤箱,泥巴塞进去,人就出来
public static Human createHuman(Class c){
Human human=null; // 定义一个类型的人类
try {
//如果MAP 中有,则直接从取出,不用初始化了
if(humans .containsKey(c.getSimpleName())){
human = humans .get(c.getSimpleName());
}else {
human = (Human)Class.forName(c.getName()).newInstance();
//放到MAP 中
humans.put(c.getSimpleName(), human);
}
} catch (InstantiationException e) {
// 你要是不说个人类颜色的话,没法烤,要白的 黑,你说话了才好烤
System.out.println("必须指定人类的颜色" );
} catch (IllegalAccessException e) {
// 一定定义的人类有问题,那就烤不出来了
System.out.println("人类定义错误!" );
} catch (ClassNotFoundException e) {
// 你随便说个人类,我到哪里给你制造去?!
System.out.println("混蛋,你指定的人类找不到!" );
}return human;
}
}
这个在类初始化很消耗资源的情况比较实用,比如你要连接硬件,或者是为了初始化一个类需要准备比较多条件(参数), 通过这种方式可以很好的减少项目的复杂程度。
网友评论