大话设计模式一:简单工厂模式(simple factory)
2013-09-03 21:09
330 查看
一. 定义:
简单工厂提供一个创建对象实例的功能,而无须关心其具体实现。
简单工厂方法的内部主要实现的功能是:选择合适的实现类来创建实例对象。
二. 结构图:
Api:定义客户端所需要的功能接口
Impl:具体实现Api的实现类,可能会有多个
Factory:工厂,选择合适的实现类来创建Api接口对象
Client:客户端,通过Factory去获取Api接口对象,面向Api接口编程
三. 序列图:
四. 接口回顾:
1. 接口是用来干嘛的?
通常用接口来定义实现类的外观,就相当于一份契约,根据外部应用需要的功能,约定了实现类应该要实现的功能。
2. 接口的思想:封装隔离
3. 使用接口的好处:
只要接口不变,内部实现的变化就不会影响到外部应用,从而使系统更灵活
4. 接口和抽象类的选择:
优先选择接口
在如下情况下选抽象类:既要定义子类的行为,又要为子类提供公共的功能。
五. 简单工厂的例子:
实例1:
定义Operation抽象类,将各种操作解耦为各个类并实现Operation抽象类,这样可以降低了各种具体操作代码耦合性。总体来说,定义一个抽象类,然后若干类继承该抽象类并实现抽象方法,工厂会根据需要生成各种子类对象(多态)。
用一个单独的类来做创建实例的过程,这就是工厂。如果现在还需要增加各种复杂运算,比如平方根,只需要增加运算子类继承Operation抽象类,同时修改运算类工厂。
注意:客户端在调用工厂的时候,需要传入参数,这就说明客户端必须知道每个参数的含义,也需要理解每个参数对应的功能处理。这就要求必须在一定程度上,向客户暴露一定的内部实现细节。
实例2:
使用反射加上配置文件,来实现添加新的实现类过后,无需修改代码,就能把这个新的实现类加入应用中。
六. 何时使用简单工厂:
1. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选择简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现。
2. 如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制。
简单工厂提供一个创建对象实例的功能,而无须关心其具体实现。
简单工厂方法的内部主要实现的功能是:选择合适的实现类来创建实例对象。
二. 结构图:
Api:定义客户端所需要的功能接口
Impl:具体实现Api的实现类,可能会有多个
Factory:工厂,选择合适的实现类来创建Api接口对象
Client:客户端,通过Factory去获取Api接口对象,面向Api接口编程
三. 序列图:
四. 接口回顾:
1. 接口是用来干嘛的?
通常用接口来定义实现类的外观,就相当于一份契约,根据外部应用需要的功能,约定了实现类应该要实现的功能。
2. 接口的思想:封装隔离
3. 使用接口的好处:
只要接口不变,内部实现的变化就不会影响到外部应用,从而使系统更灵活
4. 接口和抽象类的选择:
优先选择接口
在如下情况下选抽象类:既要定义子类的行为,又要为子类提供公共的功能。
五. 简单工厂的例子:
实例1:
定义Operation抽象类,将各种操作解耦为各个类并实现Operation抽象类,这样可以降低了各种具体操作代码耦合性。总体来说,定义一个抽象类,然后若干类继承该抽象类并实现抽象方法,工厂会根据需要生成各种子类对象(多态)。
package simple_factory; public abstract class Operation { private double numberA = 0; private double numberB = 0; public double getNumberA() { return numberA; } public double getNumberB() { return numberB; } public void setNumberA(double numberA) { this.numberA = numberA; } public void setNumberB(double numberB) { this.numberB = numberB; } public abstract double GetResult() throws Exception; public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Operation oper; oper = OperationFactory.createOperation("+"); oper.setNumberA(1); oper.setNumberB(2); double result = oper.GetResult(); System.out.println(result); } } class OperationAdd extends Operation { @Override public double GetResult() { double result = 0; result = this.getNumberA() + this.getNumberB(); return result; } } class OperationSub extends Operation { @Override public double GetResult() { double result = 0; result = this.getNumberA() - this.getNumberB(); return result; } } class OperationMul extends Operation { @Override public double GetResult() { double result = 0; result = this.getNumberA() * this.getNumberB(); return result; } } class OperationDiv extends Operation { @Override public double GetResult() throws Exception { double result = 0; if (this.getNumberB() == 0) throw new Exception("除数不能为0"); result = this.getNumberA() / this.getNumberB(); return result; } } class OperationFactory { public static Operation createOperation(String operate) { Operation oper = null; switch (operate) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; } }
用一个单独的类来做创建实例的过程,这就是工厂。如果现在还需要增加各种复杂运算,比如平方根,只需要增加运算子类继承Operation抽象类,同时修改运算类工厂。
注意:客户端在调用工厂的时候,需要传入参数,这就说明客户端必须知道每个参数的含义,也需要理解每个参数对应的功能处理。这就要求必须在一定程度上,向客户暴露一定的内部实现细节。
实例2:
使用反射加上配置文件,来实现添加新的实现类过后,无需修改代码,就能把这个新的实现类加入应用中。
/** * 某个接口(通用的、抽象的、非具体的功能的) */ public interface Api { /** * 某个具体的功能方法的定义,用test来演示一下。 */ public void test(String s); }
/** * 对某个接口的一种实现 */ public class Impl implements Api{ public void test(String s) { System.out.println("Now In Impl. The input s: " + s); } }
/** * 工厂类,用来创造Api对象 */ public class Factory { /** * 具体的创造Api的方法,根据配置文件的参数来创建接口 */ public static Api createApi() { // 直接读取配置文件来获取需要创建实例的类(使用反射) InputStream in = null; Properties p = null; Api api = null; try { in = Factory.class.getResourceAsStream("FactoryTest.properties"); p = new Properties(); p.load(in); // 用反射去创建对象 api = (Api) Class.forName(p.getProperty("ImplClass")).newInstance(); } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } return api; } }配置文件:如果新增了实现类后,修改此配置文件就可以了
ImplClass=cn.javass.dp.simplefactory.myexample.Impl
/** * 客户端:测试使用Api接口 */ public class Client { public static void main(String[] args) { Api api = Factory.createApi(); api.test("哈哈,不要紧张,只是个测试而已!"); } }
六. 何时使用简单工厂:
1. 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选择简单工厂,让客户端通过工厂来获取相应的接口,而无需关心具体实现。
2. 如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制。
相关文章推荐
- 设计模式之简单工厂模式(SimpleFactory)
- Java设计模式:简单工厂模式(Simple Factory Pattern)
- 简单工厂模式(Simple Factory Pattern)
- 设计模式——简单工厂模式(Simple Factory)
- 工厂模式—简单工厂模式(Simple Factory Pattern)
- Java设计模式 - 简单工厂模式(Simple Factory)
- 读大《话设计模式》---简单工厂模式(SimpleFactory)(一)
- 简单工厂模式(simple factory pattern)
- 简单工厂模式-Simple Factory Pattern 工厂三兄弟之简单工厂模式(四):图表库解决方案的改进,简单工厂模式的简化,简单工厂模式总结
- 设计模式——简单工厂模式(SimpleFactory Pattern)
- 解读设计模式----简单工厂模式(SimpleFactory Pattern),你要什么我就给你什么
- Java简单工厂模式(SimpleFactoryMode)
- c++设计模式:简单工厂模式(Simple Factory Pattern)
- 大话设计模式感悟(2)——简单工厂模式(Simple Factory)
- 设计模式之简单工厂模式(Simple Factory Pattern)
- 设计模式之简单工厂模式(Simple Factory)
- JAVA设计模式(01):创建型-工厂模式【简单工厂模式】(Simple Factory)
- 简单工厂模式(Simple Factory)
- 读书笔记:设计模式-简单工厂模式(SimpleFactory)
- 简单工厂模式(SimpleFactory)