Android 内功心法(1.2)——android常用设计模式之工厂模式
2016-05-04 20:57
543 查看
上一篇:Android 内功心法(1.1)—android常用设计模式之单例模式 中 我阐述了几种单例模式以及现在最好的单例模式实现方法,其中包括经典单例写法和java5之后的最佳写法。
今天就要来说说工厂模式了。
工厂负责将大量有共同接口的类实例化。工厂模式可以决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
工厂模式的使用有很多种,简单工厂(静态工厂),工厂方法,抽象工厂,工厂+策略。
今天我会一一阐述。
这是简单工厂模式的基类,一切拓展或者需要处理的类都要依赖于它。
加减乘除是四个类,我只是统一写在代码块里面,并不代表这四个类在一起。
加减乘除这四个类都继承了简单工厂的基类。也就是拥有两个参数的get/set方法和运算结果方法的Operation类。
这个类的作用就是处理逻辑。根据用户输入的符号(+-*/)来处理相对应的逻辑。
根据这个加减乘除的小栗子可以看出简单工厂模式的好处。
如果不用简单工厂模式,那么你需要实现四个逻辑,重复大量代码。后期的拓展和维护都不好做。
而是用简单工厂模式处理后的代码可以看出,逻辑清晰。若想要增加某个新功能,比如模运算,那么我们只需要新建一个OperationMi类添加如下代码:
这样,“新功能”写完了。新功能没有影响原来的任何一个功能也没有使工厂的基类改变。
而是用新功能则只需要在Operation里的switch方法中加入:
怎么样?是不是拓展性很好,而且遵循了设计模式的“最少知道原则”。
类于类之间根本没有互相通讯
这就是简单工厂或者叫静态工厂模式。写起来很简单,使用起来很方便的一个设计模式。
不过,这种设计模式也有它的缺点在里面。也常常被否定为经典24种设计模式中的一种。
它的缺点就是没有遵循“开闭原则”。对拓展开放做到了,但是没有对修改关闭。
每当添加一种工厂的时候就要在OperationFactory类中createOperation方法中添加一个case方法。
这就已经修改了代码。所以,简单工厂模式应该不符合设计模式的“要求”。
那么,简单工厂还可以进一步的进行优化。
接下来的代码是把简单工厂和策略模式混合运用。算是对简单工厂的用法进一步的优化。
将简单工厂的基类换成策略模式的基类。
可以看出,它是一个抽象类。
修改操作简单工厂的类为:
算法逻辑实现类
接下来是策略的具体实现类:
简单工厂+策略模式能够让简单工厂更加的灵活。不需要创建和实例化多个类。想要得到一个结果只需要new出一个ConcreteStrategy对象,传入想到对应的计算模式,再调用contextInterface方法,传入需要计算的值就可以得到想要的结果。
我们来比较一下:
简单工厂
简单工厂+策略
通过代码就一目了然。
简单工厂+策略模式的代码比单纯的简单工厂模式要简单的很多。
这就是通过模式的组合运用来达到简化代码的方式。
那么,接下来这种工厂就能够弥补简单工厂的缺点。
上面简单工厂的代码接着写
首先写一个工厂方法类的接口
再来写一个运算法则的具体工厂类
加上上面简单工厂的基类Operation和逻辑类OperationAdd等
就组成了工厂方法类。
使用方法:
这样一来。添加逻辑类就添加:
再添加模运算的工厂类:
这样看起来是不是就成就了两个设计模式的原则。“最少知道原则”和“开闭原则”。
“最少知道原则”在简单工厂里就已经实现了。而“开闭原则”则利用工厂接口和工厂类实现了。
这样,即便最后添加了新的逻辑运算也不用去修改代码,而是相对应的添加一个新逻辑的具体工厂类。
工厂方法模式是定义一个用于创建对iangd接口让子类去决定实例化哪一个类。
当然,看懂了“简单工厂+策略模式”的程序员们也自然能够做出“工厂方法+策略”的组合代码。
通常在面对较大改动。需要添加很多的工厂以及方法类的时候,显然我们不可能一个方法一个类的去添加。
这时候 我们就需要一种更加简单方便的方法。
需要看抽象工厂的程序员们可以看我的下一篇连载。
Android 内功心法(1.2.1)——android常用设计模式之工厂模式后续抽象工厂模式
今天就要来说说工厂模式了。
工厂负责将大量有共同接口的类实例化。工厂模式可以决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
工厂模式的使用有很多种,简单工厂(静态工厂),工厂方法,抽象工厂,工厂+策略。
今天我会一一阐述。
1,简单工厂
/** * 简单工厂模式的基类 */ public class Operation { private double numberA;//算法的第一个值 private double numberB;//算法的第二个值 public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } /**运算结果调用该方法 * @return 简单工厂处理加减乘除的运算,返回相应的结果 */ public double getResult(){ return 0; } }
这是简单工厂模式的基类,一切拓展或者需要处理的类都要依赖于它。
/** * 加法 */ public class OperationAdd extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { return getNumberA()+getNumberB(); } } /** * 减法 */ public class OperationSub extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { return getNumberA()-getNumberB(); } } /** * 乘法 */ public class OperationMul extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { return getNumberA()*getNumberB(); } } /** * 除法 */ public class OperationDiv extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { if(getNumberB()==0)return 0; return getNumberA()/getNumberB(); } }
加减乘除是四个类,我只是统一写在代码块里面,并不代表这四个类在一起。
加减乘除这四个类都继承了简单工厂的基类。也就是拥有两个参数的get/set方法和运算结果方法的Operation类。
/** * 具体操作工厂的类 */ public class OperationFactory { public static Operation createOperation(String operate) { Operation operation; switch (operate) { case "+": operation = new OperationAdd(); break; case "-": operation = new OperationSub(); break; case "*": operation = new OperationMul(); break; case "/": operation = new OperationDiv(); break; default: operation = null; break; } return operation; } }
这个类的作用就是处理逻辑。根据用户输入的符号(+-*/)来处理相对应的逻辑。
/** * 简单工厂模式的测试类 */ public class OperationTest { /**简单工厂模式说明: * 一个总代理类, * 确定好参数,传入,传出。 * 确定好使用到的方法,以便子类重写 * * 所有实现具体算法的类都要继承这个代理类 * 内部实现具体的算法 * 按照设计模式的四大原则,必须实现父类的全部方法 * * 提供一个供外部调用的类 * 外部传入参数,这个类根据参数的不同获取不懂的算法,得到不懂的结果 * 而方法的多少是根据之前写好的实现类而定 * */ private Operation operation; public void testAdd() {//+ operation = OperationFactory.createOperation("+"); operation.setNumberA(1); operation.setNumberB(2); Log.e("test", "简单工厂模式运算结果(+):" + operation.getResult()); } public void testDiv() {/// operation = OperationFactory.createOperation("/"); operation.setNumberA(1); operation.setNumberB(2); Log.e("test", "简单工厂模式运算结果(/):" + operation.getResult()); } public void testMul() {//* operation = OperationFactory.createOperation("*"); operation.setNumberA(1); operation.setNumberB(2); Log.e("test", "简单工厂模式运算结果(*):" + operation.getResult()); } public void testSub() {//- operation = OperationFactory.createOperation("-"); operation.setNumberA(1); operation.setNumberB(2); Log.e("test", "简单工厂模式运算结果(-):" + operation.getResult()); } }
根据这个加减乘除的小栗子可以看出简单工厂模式的好处。
如果不用简单工厂模式,那么你需要实现四个逻辑,重复大量代码。后期的拓展和维护都不好做。
而是用简单工厂模式处理后的代码可以看出,逻辑清晰。若想要增加某个新功能,比如模运算,那么我们只需要新建一个OperationMi类添加如下代码:
/** * 模运算 */ public class OperationMi extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { return getNumberA()%getNumberB(); } }
这样,“新功能”写完了。新功能没有影响原来的任何一个功能也没有使工厂的基类改变。
而是用新功能则只需要在Operation里的switch方法中加入:
case "%": operation = new OperationMi(); break;
怎么样?是不是拓展性很好,而且遵循了设计模式的“最少知道原则”。
类于类之间根本没有互相通讯
这就是简单工厂或者叫静态工厂模式。写起来很简单,使用起来很方便的一个设计模式。
不过,这种设计模式也有它的缺点在里面。也常常被否定为经典24种设计模式中的一种。
它的缺点就是没有遵循“开闭原则”。对拓展开放做到了,但是没有对修改关闭。
每当添加一种工厂的时候就要在OperationFactory类中createOperation方法中添加一个case方法。
这就已经修改了代码。所以,简单工厂模式应该不符合设计模式的“要求”。
那么,简单工厂还可以进一步的进行优化。
接下来的代码是把简单工厂和策略模式混合运用。算是对简单工厂的用法进一步的优化。
2,简单工厂+策略
借用简单工厂的代码,并加以稍微的修改:将简单工厂的基类换成策略模式的基类。
/* * 策略模式的基类 */ public abstract class Strategy { /**定义所有支持算法的公共接口*/ private double numberA;//算法的第一个值 private double numberB;//算法的第二个值 public double getNumberA() { return numberA; } public void setNumberA(double numberA) { this.numberA = numberA; } public double getNumberB() { return numberB; } public void setNumberB(double numberB) { this.numberB = numberB; } /** * 算法方法 */ public abstract double GetResultInterface(double a,double b); }
可以看出,它是一个抽象类。
修改操作简单工厂的类为:
public class ConcreteStrategy { /**策略模式+简单工厂模式 * 相当于用策略模式把工厂模式的调用方法简化 * 传入相应的值,就会得到相应的方法。 * 获得该算法以后 * 通过公用的接口得到算法结果或者自定义的想要的结果 * */ private Strategy strategy; /** * 初始化传入具体的策略对象 * * @param i 算法要求:加减乘除 */ public ConcreteStrategy(String i) { switch (i) { default: case "+": strategy=new ConcreteStrategyA("+"); break; case "-": strategy=new ConcreteStrategyB("-"); break; case "*": strategy=new ConcreteStrategyC("*"); break; case "/": strategy=new ConcreteStrategyD("/"); break; } } /** * 上下文的接口,根据具体的策略对象调用其算法方法 */ public void contextInterface(double a,double b) { strategy.GetResultInterface(a,b); } }
算法逻辑实现类
/* *加法类 */ public class ConcreteStrategyA extends Strategy { private String status; public ConcreteStrategyA(String status) { this.status= status; } /** * 算法A的实现 */ @Override public double GetResultInterface(double a,double b) { if(status.equals("+")) return a+b; return 0; } }
接下来是策略的具体实现类:
public class StrategyTest { private ConcreteStrategy concreteStrategy; /**选择计算模式 * @param i */ public void StrategyTest(String i) { concreteStrategy = new ConcreteStrategy(i); } /**输入金额 * @param money */ public void getResult(double a,double b) { concreteStrategy.contextInterface(a,b); } }
简单工厂+策略模式能够让简单工厂更加的灵活。不需要创建和实例化多个类。想要得到一个结果只需要new出一个ConcreteStrategy对象,传入想到对应的计算模式,再调用contextInterface方法,传入需要计算的值就可以得到想要的结果。
我们来比较一下:
简单工厂
operation = OperationFactory.createOperation("-"); operation.setNumberA(1); operation.setNumberB(2); operation.getResult();//得到结果
简单工厂+策略
concreteStrategy = new ConcreteStrategy("+"); concreteStrategy.contextInterface(1,2);//得到结果
通过代码就一目了然。
简单工厂+策略模式的代码比单纯的简单工厂模式要简单的很多。
这就是通过模式的组合运用来达到简化代码的方式。
那么,接下来这种工厂就能够弥补简单工厂的缺点。
3,工厂方法模式
借用上面简单工厂的代码接着写
首先写一个工厂方法类的接口
public interface IFactory { //创建工厂的抽象类 Operation createOperation(); }
再来写一个运算法则的具体工厂类
* 算法加减乘除 */ public class ConcreteFactoryA implements IFactory { //加法类工厂 @Override public Operation createOperation() { return new OperationAdd(); } } public class ConcreteFactoryB implements IFactory { //减法类工厂 @Override public Operation createOperation() { return new OperationSub(); } } public class ConcreteFactoryC implements IFactory { //乘法类工厂 @Override public Operation createOperation() { return new OperationMul(); } } public class ConcreteFactoryD implements IFactory { //除法类工厂 @Override public Operation createOperation() { return new OperationDiv(); } }
加上上面简单工厂的基类Operation和逻辑类OperationAdd等
就组成了工厂方法类。
使用方法:
private void testAdd() { IFactory iFactory = new ConcreteFactoryA();//实例化工厂加法 Operation operation = iFactory.createOperation();//获得加法逻辑类的实例 operation.setNumberA(1); operation.setNumberB(2); operation.getResult(); }
这样一来。添加逻辑类就添加:
public class OperationMi extends Operation { /**重写算法结果 * @return */ @Override public double getResult() { return getNumberA()%getNumberB(); } }
再添加模运算的工厂类:
public class ConcreteFactoryE implements IFactory { //加法类工厂 @Override public Operation createOperation() { return new OperationMi(); } }
这样看起来是不是就成就了两个设计模式的原则。“最少知道原则”和“开闭原则”。
“最少知道原则”在简单工厂里就已经实现了。而“开闭原则”则利用工厂接口和工厂类实现了。
这样,即便最后添加了新的逻辑运算也不用去修改代码,而是相对应的添加一个新逻辑的具体工厂类。
工厂方法模式是定义一个用于创建对iangd接口让子类去决定实例化哪一个类。
当然,看懂了“简单工厂+策略模式”的程序员们也自然能够做出“工厂方法+策略”的组合代码。
通常在面对较大改动。需要添加很多的工厂以及方法类的时候,显然我们不可能一个方法一个类的去添加。
这时候 我们就需要一种更加简单方便的方法。
3,抽象工厂模式
因为抽象工厂的实现比较麻烦,代码量比较多,所以特意拿出一章来写抽象工厂。需要看抽象工厂的程序员们可以看我的下一篇连载。
Android 内功心法(1.2.1)——android常用设计模式之工厂模式后续抽象工厂模式
相关文章推荐
- 解决No resource found that matches the given name 'android:Theme.Material.Light.DarkActionBar'
- Android 触摸事件机制(二) Activity中触摸事件详解
- Android基础 | 创建新的Activity
- Android MVP模式
- Android 沿着线绘制文字
- Android中Base64的简单使用
- Android Dev Intro - Android SurfaceTexture
- Android Dev Intro - SurfaceTexture,TextureView, SurfaceView and GLSurfaceView
- Android Dev Intro - Android Thread Intro
- Android:使用MuPdf开源库阅读PDF文件
- Android剪切板传递数据传递序列化对象数据
- 【流媒体】 Android 实时视频编码—H.264硬编码
- Android 内功心法(1.1)——android常用设计模式之单例模式
- Android_EventBus的使用
- android布局属性详解
- Android插件化开发笔记(一)
- 短信备份与恢复
- android layout属性介绍
- Android读取资源文件——读取原始Xml内容和使用Menu文件
- android 之AChartEngine绘制折线图