您的位置:首页 > 编程语言 > Java开发

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

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

工厂方法模式:

管你是白的、黑的还是黄的,反正都是人,会说会笑,所以先定义一个人类的接口(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.csdn.net/detail/github_22022001/8290541
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: