工厂方法模式——应用最广泛
2016-02-02 14:47
369 查看
(《设计模式解析与实战》读书笔记)
一、定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。它是创建型设计模式之一。
二、使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
三、工厂方法模式的通用模式代码
运行:
![](http://img.blog.csdn.net/20160202144403868)
主要分为四大模块:
(1)抽象工厂,核心;
(2)具体工厂,具体的业务逻辑;
(3)抽象产品,所创建的产品的父类;
(4)具体产品,实现抽象产品的某个具体产品的对象。
当然可以利用反射的方式更简洁的来生产具体产品对象:
这种方法简洁、动态,不需要为每一个产品都定义一个具体的工厂。
如果工厂类只有一个,那么就可以简化掉抽象类,只需要将工厂方法改为静态方法。
四、实例
以数据存储为例,将每一种数据操作的方式作为一个产品类,在抽象产品类中定义操作的方法:
演示结果:
![](http://img.blog.csdn.net/20160202144629742)
五、优缺点
优点:
(1)降低了对象之间的耦合度;
(2)将实例化的任务交由子类去完成,有非常好的扩展性;
(3)结构简单,逻辑基本类似。
缺点:
每次为工厂方法模式添加新的产品时就要编写一个新的产品类,同时还要引入抽象层,这会导致类结构的复杂化。
一、定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。它是创建型设计模式之一。
二、使用场景
在任何需要生成复杂对象的地方,都可以使用工厂方法模式。复杂对象适合使用工厂模式,用new就可以完成创建的对象无需使用工厂模式。
三、工厂方法模式的通用模式代码
/** * 抽象产品类 */ public abstract class Product { /** * 产品类的抽象方法由具体的产品类去实现 */ public abstract void method(); }
/** * 具体产品类A */ public class ConcreteProductA extends Product{ @Override public void method() { System.out.println("我是具体的产品A"); } }
/** * 具体产品类B */ public class ConcreteProductB extends Product{ @Override public void method() { System.out.println("我是具体的产品B"); } }
/** * 抽象工厂类 */ public abstract class Factory { /** * 抽象工厂方法具体生产什么由子类去实现 * * @return 具体的产品对象 */ public abstract Product createProduct(); }
/** * 具体工厂类 */ public class ConcreteFactory extends Factory { @Override public Product createProduct() { return new ConcreteProductA(); } }
/** * 客户类 */ public class Client { public static void main(String[] args) { Factory factory = new ConcreteFactory(); Product product = factory.createProduct(); product.method(); } }
运行:
主要分为四大模块:
(1)抽象工厂,核心;
(2)具体工厂,具体的业务逻辑;
(3)抽象产品,所创建的产品的父类;
(4)具体产品,实现抽象产品的某个具体产品的对象。
当然可以利用反射的方式更简洁的来生产具体产品对象:
/** * 抽象工厂类 */ public abstract class Factory { /** * 抽象工厂方法具体生产什么由子类去实现 * * @param clz * 产品对象类型 * @return 具体的产品对象 */ public abstract <T extends Product> T createProduct(Class<T> clz); } /** * 具体工厂类 */ public class ConcreteFactory extends Factory { @Override public <T extends Product> T createProduct(Class<T> clz) { Product product = null; try { product = (Product) Class.forName(clz.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) product; } } /** * 客户类 */ public class Client { public static void main(String[] args) { Factory factory = new ConcreteFactory(); Product product = factory.createProduct(ConcreteProductA.class); product.method(); } }
这种方法简洁、动态,不需要为每一个产品都定义一个具体的工厂。
如果工厂类只有一个,那么就可以简化掉抽象类,只需要将工厂方法改为静态方法。
/** * 简单工厂模式或静态工厂模式 */ public class EasyFactory { public static Product createProduct() { return new ConcreteProductA(); } }
四、实例
以数据存储为例,将每一种数据操作的方式作为一个产品类,在抽象产品类中定义操作的方法:
/** * 抽象数据存储类 */ public abstract class IOHandler { /** * 添加一条个人信息 * * @param id * 身份证号码 * @param name * 名字 */ public abstract void add(String id, String name); /** * 删除一条个人信息 * * @param id */ public abstract void remove(String id); /** * 更新一条个人信息 * * @param id * 身份证号码 * @param name * 名字 */ public abstract void update(String id, String name); /** * 查询身份证对应的人名 * * @param id */ public abstract String query(String id); } /** * 文件存储 */ public class FileHandler extends IOHandler { @Override public void add(String id, String name) { // TODO 文件存储代码 } @Override public void remove(String id) { // TODO 文件删除代码 } @Override public void update(String id, String name) { // TODO 文件修改代码 } @Override public String query(String id) { // TODO 文件查询代码 return "文件存储"; } } /** * XML文件存储 */ public class XMLHandler extends IOHandler{ @Override public void add(String id, String name) { // TODO 业务处理 } @Override public void remove(String id) { // TODO Auto-generated method stub } @Override public void update(String id, String name) { // TODO Auto-generated method stub } @Override public String query(String id) { // TODO Auto-generated method stub return "XML文件存储"; } } /** * SQLite数据库存储 */ public class DBHandler extends IOHandler { @Override public void add(String id, String name) { // TODO 业务处理 } @Override public void remove(String id) { // TODO Auto-generated method stub } @Override public void update(String id, String name) { // TODO Auto-generated method stub } @Override public String query(String id) { // TODO Auto-generated method stub return "SQLite数据库存储"; } } /** * 数据存储工厂类 */ public class IOFactory { /** * 获取IO处理者 * * @param clz * 处理类的类型 * @return IOHandler对象 */ public static <T extends IOHandler> T getIOHandler(Class<T> clz) { IOHandler handler = null; try { handler = (IOHandler) Class.forName(clz.getName()).newInstance(); } catch (Exception e) { e.printStackTrace(); } return (T) handler; } }
public class MainActivity extends Activity { private IOHandler handler; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv_text); } public void onClick(View v) { switch (v.getId()) { // 查询普通文本数据 case R.id.btn_file: handler = IOFactory.getIOHandler(FileHandler.class); mTextView.setText(handler.query("123")); break; // 查询XML文件数据 case R.id.btn_xml: handler = IOFactory.getIOHandler(XMLHandler.class); mTextView.setText(handler.query("123")); break; // 查询数据库数据 case R.id.btn_db: handler = IOFactory.getIOHandler(DBHandler.class); mTextView.setText(handler.query("123")); break; case R.id.btn_default: mTextView.setText("点击按钮查询结果"); break; default: break; } } }
演示结果:
五、优缺点
优点:
(1)降低了对象之间的耦合度;
(2)将实例化的任务交由子类去完成,有非常好的扩展性;
(3)结构简单,逻辑基本类似。
缺点:
每次为工厂方法模式添加新的产品时就要编写一个新的产品类,同时还要引入抽象层,这会导致类结构的复杂化。
相关文章推荐
- Android LayoutInflater的inflate布局文件收获
- OC中的instancetype和id关键字异同
- 更改XenServer默认安装后根分区大小
- Linux下编译安装Apache 2.4
- ping通IP,telnet 3306不通
- iTunes Connect程序被拒,如何申诉?
- ThinkPHP3.2切换数据库调用
- 使用SiteScope监控Tomcat
- 自己写的异步多线程队列
- 关于自定义card时的图片自适应.(inflate的理解)
- 解决Failed to load class "org.slf4j.impl.StaticLoggerBinder"
- Log4j进行日志记录Demo
- AsyncTask与线程的区别
- 水平ListView
- JAVA Instrumentation
- gh-pages 首次搭建遇到的坑
- BeagleboneBack 从零开始系列之三(如何启动或使用)
- 如何更好的认识自己?
- 网页性能管理详解(原作者: 阮一峰)
- 网页性能管理详解(原作者: 阮一峰)