java23种常用设计模式之工厂方法模式(Factory Method)2

工厂方法模式与随机生产人种实例

就举个比较容易理解的例子:人有白、黑、黄三种人,他们都会说会笑,无论什么肤色。类图我就省了,大家有兴趣可以画画。

工厂方法模式:

管你是白的、黑的还是黄的,反正都是人,会说会笑,所以先定义一个人类的接口(Human)

package com.freedom.factory.abstractfactory;

public interface Human {
	
	public void say();
	public void smile();

}
接着定义人种:
package com.freedom.factory.abstractfactory;

public class YellowHuman 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!");
		
	}

}

package com.freedom.factory.abstractfactory;

public class WhiteHuman implements Human{
    
    
    @Override
    public void say() {
        System.out.println("white human can say anything!");
        
    }

    @Override
    public void smile() {
        System.out.println("white human can smile!");
        
    }

}

package com.freedom.factory.abstractfactory;

public class BlackHuman 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;

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;
	}
}
test
package com.freedom.factory.abstractfactory;

import org.junit.Test;

public class TestAbstractFactory {

	@Test
	public void test() {
		System.out.println("生产的第一批人是:白人");
		Human whiteHuman = HumanFactory.createHuman(WhiteHuman.class);
		whiteHuman.say();
		whiteHuman.smile();
	}
	
	@Test
	public void test2() {
		System.out.println("生产的第二批人是:黑人");
		Human blackHuman = HumanFactory.createHuman(BlackHuman.class);
		blackHuman.say();
		blackHuman.smile();
	}
	
	@Test
	public void test3() {
		System.out.println("生产的第三批人是:黄人");
		Human yellowHuman = HumanFactory.createHuman(YellowHuman.class);
		yellowHuman.say();
		yellowHuman.smile();
	}
	

}
/*
运行结果:
生产的第一批人是:白人
white human can say anything!
white human can smile!
生产的第三批人是:黄人
yellow human can say anything!
yellow human can smile!
生产的第二批人是:黑人
black human can say anything!
black human can smile!
*/ 
当然机器总是不停地生产有时也会罢工,所以这里可以偷个懒,目前的HumanFactory只能定性生产特定人种,改造一下,让它可以批量随机生产
package com.freedom.factory.abstractfactory;

import java.util.List;
import java.util.Random;

public class HumanFactory {
	
	//批量随机生产
	public static Human createHuman(){
		Human human=null; //定义一个类型的人类
		//首先是获得有多少个实现类,多少个人种
		List<Class> concreteHumanList = ClassUtils.getAllClassByInterface(Human.class); //定义了多少人种
		//随机生产什么人种都OK
		Random random = new Random();
		int rand = random.nextInt(concreteHumanList.size());
		human = createHuman(concreteHumanList.get(rand));
		return human;
	}

	//人种定向生产
	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("Sorry,你指定的人种找不到!");
		}
		return human;
	}
	
}
test
package com.freedom.factory.factory2;

import org.junit.Test;

public class TestFactory2 {

	@Test
	public void test() {
		for(int i=0; i<10; i++){
			System.out.println("---随机生产---" + i);
			Human human = HumanFactory.createHuman();
			human.say();
			human.smile();
			}
	}
	
}
/*
---随机生产---0
black human can say anything!
black human can smile!
---随机生产---1
black human can say anything!
black human can smile!
---随机生产---2
black human can say anything!
black human can smile!
---随机生产---3
white human can say anything!
white human can smile!
---随机生产---4
black human can say anything!
black human can smile!
---随机生产---5
white human can say anything!
white human can smile!
---随机生产---6
black human can say anything!
black human can smile!
---随机生产---7
black human can say anything!
black human can smile!
---随机生产---8
yellow human can say anything!
yellow human can smile!
---随机生产---9
yellow human can say anything!
yellow human can smile!
*/
 
总结一下,增加了createHuman()后,是不是这个工厂的扩展性更好了?你看你要再加一个人种,只要你继续集成Human 接口成了,然后啥都不用修改就可以生产了,具体产多少,随便你说了算,普通工厂模式就是这么简单,然后我们再引入一个问题:人是有性别的呀,有男有女,你这怎么没区别,别急,继续往下看!
工厂方法模式还有一个非常重要的应用,就是延迟始化(Lazy initialization),什么是延迟始化呢?一个对象初始化完毕后就不释放,等到再次用到得就不用再次初始化了,直接从内存过中拿到就可以了,怎么实现呢,很简单,看例子:
package com.freedom.factory.factory2;

import java.util.HashMap;

public class HumanFactory2 {
	// 定义一个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;
	}
}
好了,这还只是工厂方法模式,我想做些拓展,比如白人有男人女人,其他人种也是,这个扩展看似很简单,只要修改各个人种的工厂类就可以了,但是这样做有什么不好呢?违反了闭包原则。那有什么方法可以避免呢?抽象方法继续看下次……


下载源码:http://download.youkuaiyun.com/detail/github_22022001/8290541

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值