工厂方法模式(java 设计模式)
1.工厂方法模式的定义
工厂方法模式使用的频率非常高, 在我们日常的开发中总能见到它的身影。 其定义为:
Define an interface for creating an object,but let subclasses decide which class to
instantiate.Factory Method lets a class defer instantiation to subclasses.( 定义一个用于创建对象的
接口, 让子类决定实例化哪一个类。 工厂方法使一个类的实例化延迟到其子类。 )
2.工厂方法模式的通用代码
抽象产品类
public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
//抽象方法
public abstract void method2();
}
具体的产品类可以有多个, 都继承于抽象产品类, 其源代码如代码清单8-9所示。
具体产品类
public class ConcreteProduct1 extends Product {
public void method2() {
//业务逻辑处理
}
}
public class ConcreteProduct2 extends Product {
public void method2() {
//业务逻辑处理
}
}
抽象工厂类负责定义产品对象的产生, 源代码如代码清单8-10所示。
抽象工厂类
public abstract class Creator {
/*
* 创建一个产品对象, 其输入参数类型可以自行设置
* 通常为String、 Enum、 Class等, 当然也可以为空
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体如何产生一个产品的对象, 是由具体的工厂类实现的,
具体工厂类
public class ConcreteCreator extends Creator {
public <T extends Product> T createProduct(Class<T> c){
Product product=null;
try {
product = (Product)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
//异常处理
}
return (T)product;
}
}
场景类
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
/*
* 继续业务处理
*/
}
}
3.工厂方法模式实例
package ch08; public interface Human {
// 人都有肤色
public void getColor();
// 人都分语言
public void getTalk();
}
package ch08; public class BlackHuman implements Human { public void getColor() {
// TODO Auto-generated method stub
System.out.println("黑人肤色为黑色"); } public void getTalk() {
// TODO Auto-generated method stub
System.out.println("黑人说话一般听不懂");
} }
package ch08; public class WhiteHuman implements Human{ public void getColor() {
// TODO Auto-generated method stub
System.out.println("白人肤色为白"); } public void getTalk() {
// TODO Auto-generated method stub
System.out.println("白人一般说英语");
} }
package ch08; public class YellowHuman implements Human{ public void getColor() {
// TODO Auto-generated method stub
System.out.println("黄色人种肤色为黄色");
} public void getTalk() {
// TODO Auto-generated method stub
System.out.println("黄色人种一般说汉语");
} }
package ch08; public abstract class AbstractHumanFactory {
//泛型 通过定义泛型对creatHuman的输入参数产生两层限制: 必须是Class类型;必须是Human的实现类。
public abstract <T extends Human> T createHuman(Class<T> c);
// 泛型类可看作普通类的工厂 /**
*
* @author
* 泛型方法,定义一个带有类型参数的简单方法
* 这个方法是在普通类中定义的,而不是在泛型类中定义的。然而,这是一个泛型方法,可
以从尖括号和类型变量看出这一点。注意,类型变量放在修饰符(这里是public static)的后面,
返回类型的前面。
*/
/*class ArrayAlg
{
public static <T> T getMiddle(T... a)
{
return a[a.length / 2];
}
}*/ }
package ch08; public class HumanFactory extends AbstractHumanFactory{ public <T extends Human> T createHuman(Class<T> c) {
// TODO Auto-generated method stub
//定义一个生产的人种;
Human human = null; try {
/* 产生一个人种, 通过Class.forName(c.getName()).newInstance()实例化一个
c对象然后再把c对象强制转化为Human或T类型的对象*/
/*Class.forName(xxx.xx.xx) 返回的是一个类, .newInstance() 后才创建一个对象*/
// human = (T) Class.forName(c.getName()).newInstance();//也对
human = (Human) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return (T)human; } }
package ch08;
//女娲类
public class NvWa {
public static void main(String[] args) {
//声明一个造人的阴阳八卦炉
AbstractHumanFactory YingYangLu = new HumanFactory();
//女娲第一次造人,火候不足,于是白人产生了
System.out.println("--造出的第一批人是白色人种--");
// 现在, Class类是泛型的。 WhiteHuman.class实际上是一个Class<WhiteHuman>(应该是Class<Human>类的对象
// (事实上,是惟一的对象)。
Human whiteHuman = YingYangLu.createHuman(WhiteHuman.class); whiteHuman.getColor();
whiteHuman.getTalk();
System.out.println("--造出的第二批人是黑色人种--");
Human blackHuman = YingYangLu.createHuman(BlackHuman.class);
blackHuman.getColor();
blackHuman.getTalk();
//第三次造人,火候刚刚好,于是黄色人种产生了
System.out.println("--造出的第三批人是黄色人种--");
Human yellowHuman = YingYangLu.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.getTalk(); }
}
4.工厂方法模式的优点
首先, 良好的封装性, 代码结构清晰。 一个对象创建是有条件约束的, 如一个调用者需
要一个具体的产品对象, 只要知道这个产品的类名( 或约束字符串) 就可以了, 不用知道创
建对象的艰辛过程, 降低模块间的耦合。
其次, 工厂方法模式的扩展性非常优秀。 在增加产品类的情况下, 只要适当地修改具体
的工厂类或扩展一个工厂类, 就可以完成“拥抱变化”。 例如在我们的例子中, 需要增加一个
棕色人种, 则只需要增加一个BrownHuman类, 工厂类不用任何修改就可完成系统扩展。
再次, 屏蔽产品类。 这一特点非常重要, 产品类的实现如何变化, 调用者都不需要关
心, 它只需要关心产品的接口, 只要接口保持不变, 系统中的上层模块就不要发生变化。 因
为产品类的实例化工作是由工厂类负责的, 一个产品对象具体由哪一个产品生成是由工厂类
决定的。 在数据库开发中, 大家应该能够深刻体会到工厂方法模式的好处: 如果使用JDBC
连接数据库, 数据库从MySQL切换到Oracle, 需要改动的地方就是切换一下驱动名称( 前提
条件是SQL语句是标准语句) , 其他的都不需要修改, 这是工厂方法模式灵活性的一个直接
案例。
工厂方法模式(java 设计模式)的更多相关文章
- 设计模式之第1章-工厂方法模式(Java实现)
设计模式之第1章-工厂方法模式(Java实现) “我先来”,“不,老公,我先!”.远远的就听到几个人,哦不,是工厂方法模式和抽象工厂模式俩小夫妻在争吵,尼妹,又不是吃东西,谁先来不都一样(吃货的世界~ ...
- 设计模式之工厂方法模式(Java实现)
“我先来”,“不,老公,我先!”.远远的就听到几个人,哦不,是工厂方法模式和抽象工厂模式俩小夫妻在争吵,尼妹,又不是吃东西,谁先来不都一样(吃货的世界~).“抽象工厂模式,赶紧的自我介绍,工厂方法模式 ...
- 工厂方法模式--java代码实现
工厂方法模式 工厂方法模式,对简单工厂模式进行了升级.我们将水果园比作一个工厂,在简单工厂模式下,水果园是一个具体的工厂,直接用来生产各种各样的水果.那么在工厂方法模式下,水果园是一个抽象工厂,那么苹 ...
- FactoryMethodPattern(工厂方法模式)-----Java/.Net
也就是工厂方法(FactoryMethod)模式允许将产品类的实例化推迟到具体的创建者子类,由创建者子类决定实例化哪一个产品类.我们同样以汽车的生产作为讲解该模式的例子,因为汽车生产从宏观上来说也是特 ...
- 工厂方法模式(JAVA反射)
简单工厂模式的不足 在简单工厂模式中,只提供了一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类.简单工厂模式最大的缺点是当有新 ...
- Java设计模式(二) 工厂方法模式
本文介绍了工厂方法模式的概念,优缺点,实现方式,UML类图,并介绍了工厂方法(未)遵循的OOP原则 原创文章.同步自作者个人博客 http://www.jasongj.com/design_patte ...
- JAVA设计模式--工厂方法模式
工厂方法设计模式 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关.是具体工厂角色必须实现的接口或者必须继承的父类.在java中它由抽象类或者接口来实现.具体工厂角色:它含有和具体业务逻辑有关 ...
- java 23 - 1 设计模式之工厂方法模式
转载: JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
- Java设计模式之工厂模式(简单工厂模式+工厂方法模式)
摘自http://blog.csdn.net/jason0539/article/details/23020989 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是 ...
- 我的Java设计模式-工厂方法模式
女朋友dodo闹脾气,气势汹汹的说"我要吃雪糕".笔者心里啊乐滋滋的,一支雪糕就能哄回来,不亦乐乎?! 但是,雪糕买回来了,她竟然说"不想吃雪糕了,突然想吃披萨" ...
随机推荐
- Ecshop布局参考图
文章列表页: article_cat.dwt 文章内容页: article.dwt 商品品牌页: brand.dwt 所有分类页: catalog.dwt 商品列表页: category.dwt 商品 ...
- 新写PHP HTTP断点续传类文件代码
一个支持断点续传的PHP文件下载类文件,调用方法简单,类代码简洁,可记忆上次的下载的节点,实现累积下载,类名称download,类代码如下: function download($path,$file ...
- RequireJS学习笔记(转)
前言 进入移动前端是很不错的选择,这块也是我希望的道路,但是不熟悉啊... 现在项目用的是require+backbone,整个框架被封装了一次,今天看了代码搞不清楚,觉得应该先从源头抓起,所以再看看 ...
- Python自动化运维之2、运算符与数据类型
python对象的相关术语: python程序中保存的所有数据都是围绕对象这个概念展开的: 程序中存储的所有数据都是对象 每个对象都有一个身份.一个类型和一个值 例如,school='MaGe Lin ...
- AngularJs 如何监视外部变量是否改变? 如何使用$cookieStore保存cookie?
1. 如何监视外部变量是否改变? 如果我们要求:在$scope之外改变一个外部变量时,触发一些操作.我们可以将外部变量写进$watch中,如图中所示.返回的n表示newValue,即新的值.o表示ol ...
- PHP and java
问题补充: 为什么不选用优秀的ASP.NET,京东做的不是很成功嘛?-----------------------------------------------------------------首 ...
- GUI(主)线程与子线程之间的通信(用信号槽通讯)
在主线程上,可以控制子线程启动,停止,清零 如果子线程启动的话,每一秒钟会向主线程发送一个数字,让主线程更新界面上的数字. 程序截图: 上代码: #include <QtGui> #inc ...
- hibernate 映射<五>多对多双向映射
多对多映射,可以分单向映射和双向映射.无论是单向还是多向那一方维护,还是双方维护,生成的表结构是一样的. 订单order和产品product是对多对的关系,就是多个订单可以对应多个产品,多个产品也可以 ...
- Android Activity整体管理和关闭工具类封装
如何彻底退出程序,在任意位置退出程序,如何管理当前的运行栈,知道activity的堆栈结构等,本文封装了一个Activity管理类,可以方便随时退出程序. /** * 应用程序Activity管理类: ...
- linux教程之四
相信不少想学习linux的新手们正愁不知道看什么linux学习教程好,下面小编给大家收集和整理了几点比较重要的教程,供大家学习,如需想学习更多的话,可到wdlinux学堂寻找更多教程. linux ...