项目中遇到这样的一个需求:分别需要对发送的数据和接受的数据做编码和解码处理,且不同的设备编码和解码方式不同。一般写法是根据不同的设备选择相应的编码和解码方式。但是这种方法耦合性高,不易维护,增加设备的支持就需要修改原先的代码,这容易在原本正确的代码中引入新的错误,这也违背了开闭原则。对于这种情况,一种较好的解决方式就是策略模式。
转载请注明出处:www.facex.xyz,如有发现错误或有其他更好的实现方式可与我联系。
开闭原则:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是封闭的。
1. 策略模式的定义
策略模式定义了一系列算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而存在。
2. 策略模式的使用场景
- 针对同一问题的多种处理方式,仅仅是具体行为有差别时。
- 需要安全的封装多种同一类型的操作时。
- 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。
4. UML类图

5. 重构步骤
-
首先定义设备解码编码策略接口类:DeviceCodecStrategy,类中定义decode和encode两个虚拟方法。
public interface DeviceCodecStrategy { /** * Author: www.facex.xyz * 解码 */ int decode(int data); /** * Author: www.facex.xyz * 编码 */ int encode(int data); }
-
定义设备A编码解码策略实现类:DeviceAStrategy,该类实现DeviceCodecStrategy接口。
public class DeviceAStrategy implements DeviceCodecStrategy { @Override public int decode(int data) { /** * Author: www.facex.xyz * 设备A解码相关方法,这里将需要解码的信息-1 */ return data - 1; } @Override public int encode(int data) { /** * Author: www.facex.xyz * 设备A编码相关方法,这里将需要解码的信息+1 */ return data + 1; } }
-
定义角色类:DeviceCodec
public class DeviceCodec { private DeviceCodecStrategy mStrategy; public void setStrategy(DeviceCodecStrategy strategy) { this.mStrategy = strategy; } public int decode(int data) { return mStrategy.decode(data); } public int encode(int data) { return mStrategy.encode(data); } }
-
使用策略模式
public static void main(String[] args) { DeviceCodec deviceCodec = new DeviceCodec(); /** * Author: www.facex.xyz * 设置解码编码策略 */ deviceCodec.setStrategy(new DeviceAStrategy()); /** * Author: www.facex.xyz * 编码 */ System.out.println("设备A编码后:" + deviceCodec.encode(10)); /** * Author: www.facex.xyz * 解码 */ System.out.println("设备A解码后:" + deviceCodec.decode(10)); }
输出结果如下,符合预期:
设备A编码后:11
设备A解码后:9
-
现在我们要支持新的DeviceB设备,同DeviceA,定义设备B编码解码策略实现类:DeviceBStrategy,实现DeviceCodecStrategy接口,使用方式同DeviceA。
public class DeviceBStrategy implements DeviceCodecStrategy { @Override public int decode(int data) { /** * Author: www.facex.xyz * 设备B解码相关方法,这里将需要解码的信息-2 */ return data - 2; } @Override public int encode(int data) { /** * Author: www.facex.xyz * 设备B编码相关方法,这里将需要解码的信息+2 */ return data + 2; } }
6. 总结
使用策略模式重构代码后,隐藏了编码解码实现,同时可扩展性变强。以后新增加设备只需要实现DeviceCodecStrategy接口,重现decode和encode方法即可,不仅符合了开闭原则,而且逻辑性更强。
参考文献:《Android源码设计模式解析与实战》