创建对象_工厂方法(Factory Method)模式 与 静态工厂方法
工厂方法模式:
- 客户类不关心使用哪个具体类,只关心该接口所提供的功能;
- 创建过程比较复杂,例如需要初始化其他关联的资源类,读取配置文件等;
- 接口有很多具体实现或者抽象有很多具体子类时,你可能需要为客户代码写一大串 if-else 逻辑来决定运行时使用哪个具体实现或者具体子类;
- 不希望给客户程序暴露过多此类的内部结构,隐藏这些细节可以降低耦合度;
- 优化性能,比如缓存大对象或者初始化比较耗时的对象。
//工厂接口定义了 createProduct()方法来放回 Product 类型的实例对象
public interface Factory { // 如果具体实现较多,定义一个参数化的工厂方法,根据不同的参数返回不同的子类
Product createProduct(String type);
} //工厂接口实现类
public class ConcreteFactory implements Factory { // 如果具体实现较多,定义一个参数化的工厂方法,根据不同的参数返回不同的子类
@Override
public Product createProduct(String type) {
if ("type1".equals(type)) {
return new ConcreteProduct1();
} else if ("type2".equals(type)) {
return new ConcreteProduct2();
} else {
return new ConcreteProduct3();
}
}
} //定义产品统一接口
public interface Product { }
//不同的产品实现
public class ConcreteProduct1 implements Product { }
public class ConcreteProduct2 implements Product { }
public class ConcreteProduct3 implements Product { }
public class Client {
private Factory factory;
public Client(Factory factory) {
this.factory = factory;
}
public void dosomething(String type) {
Product product = factory.createProduct(type);
// to do something
}
public static void main(String[] args) {
// 实例化工厂
Client client = new Client(new ConcreteFactory());
// 传入参数给工厂得到指定的产品实例
client.dosomething("type1");
}
}
静态工厂方法:
- 优点:
- 可以为静态工厂选择合适的命名,提高程序的可读性。
- 静态工厂和工厂模式一样,可以封装复杂的初始化过程,实现实例的缓存。
- 还可以根据不同的输入返回不同实现类/具体类对象。
- 缺点:
- 一般为了强迫使用工厂方法,不直接使用构造方法来构造实例,我们会强迫类只含有私有或是default的构造方法,这样,会导致此类不能被子类化。
- 如果添加了一个新的该类的子类(该类有非私有的构造方法),此静态工厂方法可能需要重写,以加入该子类的实例化过程,导致扩展性不强。
- 静态方法没有面向对象的特征,比如继承、动态多态等,不可被覆写(Overwritten)。
- 采用构造函数实例化对象,是语言的规范,而静态工厂方法与其他的静态方法没有区别,就增加了用户使用的区别。但这可以尽量采用一些家喻户晓的名字解决,让用户看到改名字就知道该方法是静态工厂方法。如getInstance( )。
- 静态工厂方法代表了一种对规范的背离。
- 使程序具有更好的可读性。静态工厂方法可以突破构造函数不能自由命名的限制,对于不同的工厂方法可以采用不同的会意的名字。JAVA平台库的java.text.Format的子类NumberFormat就有getInstance() , getPrecentInstance() , getCurrencyInstatnce()等静态方法,通过不同的名字产生特定的对象。
- 加大了程序设计和使用的灵活行。静态工厂方法是用来产生对象用的,至于产生什么类型的对象没有限制,这就意味这只要返回原返回类型或原返回类型的子类型都可以;或者是否会创建一个新的对象完全取决于方法的实现。如java.util集合框架就采用了这种优势,这样就可以更好达到封装的目的,降低API的数目和用户的使用难度,java.util.Connections是集合框架的辅助类用于对原有的集合类进行进一步封装,产生一些同步的集合,不可修改的视图。都是采用静态工厂方法实现的,至于方法内部的实现类就完全别封装了。也迫使我们使用接口编程。
- 解耦。静态工厂方法所创建的对象可以在编译时不存在,动态创建对象,采用反射,类似Spring 的 IOC容器方转。达到对象的创建与使用分离,使对象的客户和对象之间解耦,增加程序的灵活性和可扩展性。
- 单例类:只有惟一的实例的类。
- 枚举类:实例的数量有限的类。
- 具有实例缓存的类:能把已经创建的实例暂且存放在缓存中的类。
- 具有实例缓存的不可变类:不可变类的实例一旦创建,其属性值就不会被改变。
public static Boolean getTrue () {
return Boolean.TRUE;
}
创建对象_工厂方法(Factory Method)模式 与 静态工厂方法的更多相关文章
- 工厂方法模式(Factory Method)和抽象工厂模式(Abstact Factory)
分类 工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的.工厂模式在<Java 与模式>中分为三类:1)简单工厂模式(Simple Facto ...
- [设计模式-创建型]工厂方法(Factory Method)
概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- Spring 通过工厂方法(Factory Method)来配置bean
Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...
- Factory Method模式
Factory Method(工厂方法)模式属于GoF设计模式中的创建型分组,它用于在不之制定待创建对象的具体类的情况下创建对象.--<asp.net设计模式> 说白了就是一个人想要出国旅 ...
- 设计模式(四)Factory Method模式
简单来说,用Template Method模式来构建生成实例的工厂,就是Factory Method模式.在这个模式中,父类决定实例的生成方式,但不决定所要生成的具体的类,具体的处理全部交给子类负责. ...
- 设计模式之Factory Method模式
作用:将实例的生成交给子类 用Template Method模式来构建生成实例的工厂,这就是Factory Method模式. 在Factory Method中,父类决定实例的生成方式,但并不决定所要 ...
- 设计模式初学者笔记:Factory Method模式
如果要选择一种最多人熟悉的Factory Method模式的具体应用,那么就应该是MFC的App/Doc架构了.Factory Method主要在类框架中使用,以解决以下问题:框架必须实例化类,但框架 ...
- Head First 设计模式 —— 09. 模版方法 (Template Method) 模式
模板方法模式 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤. P289 特点 主导算法框架,并且保护这个算法 P28 ...
随机推荐
- UIView UITableView 背景图片添加
这几天,经常用到为某个视图设置背景图片,而API中UIView没有设置背景图片的方法,搜集归纳如下: 第一种方法: 利用的UIView的设置背景颜色方法,用图片做图案颜色,然后传给背景颜色. UICo ...
- EF小节
EF学习笔记——生成自定义实体类 http://blog.csdn.net/leftfist/article/details/24889819 --工具: 1.entity developer 2.D ...
- javaScript return false
在大多数情况下,为事件处理函数返回false,可以防止默认的事件行为.例如,默认情况下点击一个<a>元素,页面会跳转到该元素href属性指定的页. Return False 就相当于终止 ...
- erlang自定义数据类型
Erlang系统自带的基础数据类型有:atom.tuple.list.binary.pid.float.number.port.reference.record. 用户可以通过通过命令type来自定义 ...
- js查看浏览器类型和版本
var Sys = {}; var ua = navigator.userAgent.toLowerCase(); var s; var scan; (s = ua.match(/msie ([\d. ...
- LNMP环境下压力测试时的主要调试参数
LNMP环境下压力测试时的主要调试参数: 进行HTTP的压力测试时,很多时候会遇到很小的并发数,服务器就会出现不响应,或者连接超时,一般导致的原因有如下几点: 一.Nginx主要调试参数 主模块参数: ...
- 10分钟学会基于ASP.NET的 JQuery实例 (转)
本文介绍如何在ASP.NET(ASP.NET/AJAX)里使用基于JQuery的AJAX技术.(源代码下载见最后) 在使用JQuery前,请到www.jquery.com下载最新版本的js代码,然后再 ...
- C++ 内存泄露处理方法 (转)
1.可以显示内存泄露情况,但无法找到具体的文件位置写法 包含头文件#include <crtdbg.h> 然后在需要检测内存泄露的位置加上语句 _CrtDumpMemoryLeaks(); ...
- 内存泄露调试之 visual leak detector 工具【转】
本文参考此文:http://kangzj.net/visual-leak-detector-download/ 另外一种检查内存泄露的工具:visual leak detector 简称 vl ...
- Oracle 自己主动诊断资料档案库 (ADR)、自己主动诊断工作流、ADRCI工具
1.自己主动诊断工作流: 通过一个始终处于打开状态的内存中跟踪工具,数据库组件能够在第一次出现严重错误故障时捕获诊断数据.系统将自己主动维护一个称为"自己主动诊断资料档案库"的特殊 ...