Java设计模式之工厂方法

那这个过程我们就用程序来表现,首先定义一个人类的总称:

public interface Human {
//首先定义什么是人类
//人是愉快的,会笑的,本来是想用smile表示,想了一下laugh更合适,好长时间没有大笑了;
public void laugh();
//人类还会哭,代表痛苦
public void cry();
//人类会说话
public void talk();
}

然后定义具体的人种:

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("黑人可以说话,一般人听不懂");
}
}
/**
*
*
* 今天讲女娲造人的故事,这个故事梗概是这样的:
* 很久很久以前,盘古开辟了天地,用身躯造出日月星辰、山川草木,天地一片繁华
* One day,女娲下界走了一遭,哎!太寂寞,太孤独了,没个会笑的、会哭的、会说话的东东
* 那怎么办呢?不用愁,女娲,神仙呀,造出来呀,然后捏泥巴,放八卦炉(后来这个成了太白金星的宝
贝)中烤,于是就有了人:
* 我们把这个生产人的过程用Java程序表现出来:
*/
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;
}
}
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();
//第三批人了,这次火候掌握的正好,黄色人种(不写黄人,免得引起歧义),备注:RB人不属
于此列
System.out.println("\n\n------------造出的第三批人是这样的:黄色人种
-----------------");

Human yellowHuman = HumanFactory.createHuman(YellowHuman.class);
yellowHuman.cry();
yellowHuman.laugh();
yellowHuman.talk()
}
}

这样这个世界就热闹起来了,人也有了,但是这样创建太累了,神仙也会累的,那怎么办?神仙就想

了:我塞进去一团泥巴,随机出来一群人,管他是黑人、白人、黄人,只要是人就成(你看看,神仙都偷

懒,何况是我们人),先修改类图:

然后看我们的程序修改,先修改HumanFactory.java,增加了createHuman()方法:
package com.cbf4life;
import java.util.List;
import java.util.Random;
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;
}
//女娲生气了,把一团泥巴塞到八卦炉,哎产生啥人种就啥人种
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;
}
}

然后看女娲是如何做的:

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();
//第三批人了,这次火候掌握的正好,黄色人种(不写黄人,免得引起歧义),备注:RB人不属
于此列
System.out.println("\n\n------------造出的第三批人是这样的:黄色人种
-----------------");
Human yellowHuman = HumanFactory.createHuman(YellowHuman.class);
yellowHuman.cry();
yellowHuman.laugh();
yellowHuman.talk();
//女娲烦躁了,爱是啥人种就是啥人种,烧吧
for(int i=0;i<10000000000;i++){
System.out.println("\n\n------------随机产生人种了-----------------" +
i);
Human human = HumanFactory.createHuman();
human.cry();
human.laugh();
human.talk();
}
}
}
public class ClassUtils {
//给一个接口,返回这个接口的所有实现类
public static List<Class> getAllClassByInterface(Class c){
List<Class> returnClassList = new ArrayList<Class>(); //返回结果
//如果不是一个接口,则不做处理
if(c.isInterface()){
String packageName = c.getPackage().getName(); //获得当前的包名
try {
List<Class> allClass = getClasses(packageName); //获得当前包下以
及子包下的所有类
//判断是否是同一个接口
for(int i=0;i<allClass.size();i++){
if(c.isAssignableFrom(allClass.get(i))){ //判断是不是一个接口
if(!c.equals(allClass.get(i))){ //本身不加进去
returnClassList.add(allClass.get(i));
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}
return returnClassList;
}
//从一个包中查找出所有的类,在jar包中不能查找
private static List<Class> getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread()
.getContextClassLoader();
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
}
private static List<Class> findClasses(File directory, String packageName)
throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." +
file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' +
file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}

}

工厂方法模式还有一个非常重要的应用,就是延迟始化(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;
}
}

你要连接硬件,或者是为了初始化一个类需要准备比较多条件(参数),通过这种方式可以很好的减少项目的复杂程度。

时间: 2024-11-10 13:18:15

Java设计模式之工厂方法的相关文章

Java设计模式之工厂方法模式(转) 实现是抽象工厂?

Java设计模式之工厂方法模式 责任编辑:覃里作者:Java研究组织   2009-02-25   来源:IT168网站 文本Tag: 设计模式 Java [IT168 技术文章]          一 .工厂方法(Factory Method)模式 工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色

Java设计模式之工厂方法模式

工厂方法模式介绍 有时候,由于产品的多样化,但是产品的功能却有某种共同的联系.我们希望定义一个用于创建产品对象的公共接口,让子类决定去如何实现这个功能.然后,我们定义一个生产产品的"工厂",所有的产品将从这个工厂里面生产出来,这样我们就使得产品的构造的细节与工厂分离了,这样产品的实现细节就被封装起来了,并且产品的可扩展性也很强.那么,这种设计模式我们称为工厂方法模式.具体的实例有很多,比如说去年的某一阵子脸萌软件爆红,其中就运用到了工厂方法模式来给用户生产各种脸型. 工厂方法模式分类

【java】 java 设计模式(1):工厂方法模式(Factory Method)

工厂方法模式分为三种: 1.普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建.首先看下关系图: 举例如下:(我们举一个发送邮件和短信的例子) 首先,创建二者的共同接口:   public interface Sender { public void send(); } 其次,创建实现类: public class MailSender implements Sender { @Override public void send() { System.out.println

java设计模式:工厂方法模式(Factory Method)

工厂方法模式 返回设计模式目录 阅读目录: 简单工厂模式 介绍 UML类图 参考代码 总结 工厂方法模式 介绍 UML类图 参考代码 总结 前言: <大话设计模式>里有一小节叫'活字印刷,面向对象'的,讲了一个小故事,大意如下: 话说三国时期,曹操带领大军驻扎于赤壁.军船相连,气势恢宏,眼看要灭掉东吴,统一天下,曹操甚悦,于是大宴群臣.席间曹操诗兴大发,不觉吟道:"喝酒唱歌,人生真爽.--".众文武齐呼:"丞相好诗!".于是一臣子速命印刷工匠刻板印刷,以

Java 设计模式(四)-工厂方法模式 (FactoryMethod Pattern)

1     概念定义 1.1   定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 1.2   类型 创建类模式 2     原理特征 2.1   类图 2.2   优点 1)封装性良好,代码结构清晰 2)可拓展性高,只需修改一下工厂方法或拓展一个工厂类 3)屏蔽产品类,调用者不需要关心产品类的变化 4)高度解耦,高层模块只需知道产品抽象类,无需关注实现 2.3   缺点 代码复杂度增加 3     .应用拓展 3.1   应用场景 1)    

浅谈JAVA设计模式之——工厂方法(FactoryMethod)

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/45440937 一.概述 定义一个用于创建对象的接口,让子类决定实例化哪一个类.FactoryMethod使一个类的实例化延迟到其子类. 二.适用性 当一个类不知道它所必须创建的对象的类的时候. 当一个类希望由它的子类来指定它所创建的对象的时候. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候. 三.参与者 1.Produc

Java设计模式(2)——工厂方法模式

工厂方法模式同样属于类的创建型模式又被称为多态工厂模式.工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中.核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品. 一.模式中包含的角色及其职责 1.抽象工厂(Creator)角色 工厂方法模式的核心,任何工厂类都必须实现这个接口.2.具体工厂( Concrete Creator) 角色

java设计模式之工厂方法设计模式

1.定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,FactoryMethod使一个类的实例化延迟到其子类. 2.意识图 3.代码示例 联想工厂创建联想的电脑,戴尔创建戴尔的电脑 1)电脑接口 /** * 电脑接口 * [email protected] * 2017年12月25日 */ public interface Computer { /** * 描述-->一句话简介 * @param description 描述语 */ public void describe(Strin

浅析JAVA设计模式之工厂模式(一)

1 工厂模式简介 工厂模式的定义:简单地说,用来实例化对象,代替new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式可以动态决定将哪一个类实例化,不用先知道每次要实例化哪一个类. 工厂模式可以分一下三种形态: 简单工厂 (Simple Factory)模式:又称静态工厂模式(StaticFactory). 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory). 抽象工厂 (Abstract Factroy)模式:又称工具箱模式