|
场景:当我们接收到一些数据需要对其进行处理时,由于它们来自于不同的渠道(如:腾讯,头条),不同渠道所需的处理方式不同,下面我们写一个简单Demo来实现该的场景。 9 J: J) o$ Y. m' _" x+ d2 j6 ~5 {* f解决思路! G3 N Z; \ I ] 1、首先构建一个 GeneralChannelRule 基础规则抽象类,定义一个抽象方法process(),不同的渠道都需要实现该抽象方法。 public abstract void process(); } * d0 {' k# E) Z; C 2、编写一个腾讯的规则类,定义具体对于腾讯渠道数据的处理逻辑 2 d7 k- d" o2 r public class TencentChannelRule extends GeneralChannelRule@Override public void process() { // Tencent处理逻辑6 a/ G6 i8 q$ n: D0 u } }6 r, O* s2 q. ~/ _% d / I) P1 E3 @: f$ X 3、编写一个头条的规则类,定义具体对于头条数据的处理逻辑 @Override public void process() {! j+ u8 H3 k& h* a9 t: m% e% U& Y // TouTiao处理逻辑# _+ M' b0 J, p6 W3 g& z" L }2 A5 K* }! d4 F, q+ A' } } 4、建立一个简单的枚举类 /**+ p" L6 n/ E- o x( N( ^& A/ Z * 头条! I" d) g# b6 ^3 ]% M& z$ K; a6 Q7 I *// {# K2 w; Q# ^* m2 N+ e' ] TOUTIAO("TOUTIAO"), /** * 腾讯% D% N8 ?8 s2 v0 } */0 ~/ x) N5 c1 l! L TENCENT("TENCENT"),2 @0 W ?# g# M, y5 k ;0 E# z3 F! f% h6 y8 L ....# n: S6 E9 } [3 E& l( r }5 C. V, |4 a4 C; Y# c8 d 5、使用规则对数据进行处理。 ( V# W0 ^7 B9 d, P7 Q8 c: j' } public static void main(String[] args) {//这里我们模拟接收到的数据,其渠道为为TOUTIAO,来自头条的数据0 @. g6 e% g7 p1 ?+ C- x String sign = "TOUTIAO";- ^- w0 S2 n- d, q% l. A GeneralChannelRule rule;0 b# C. y8 j* J; H //根据对应渠道获取对应的具体规则实现类 if (ChannelRuleEnum.TENCENT.code.equals(sign)) {/ }0 J4 {: S5 h/ \ rule = new TencentChannelRule();' A' D0 a) g r7 N } else if (ChannelRuleEnum.TOUTIAO.code.equals(sign)) { rule = new TouTiaoChannelRule(); } else { //匹配不到6 Y3 A" t" }, ?0 j1 U4 f' i9 ] } //执行7 Q7 c& d0 A; U/ c. ? rule.process(); } 解析:如果通过上面的方式,则存在则两个缺点。 当我们需要新增新的渠道的时候,需要对main方法中的逻辑进行修改调整。这违背了设计模式中的开放封闭规则。开放封闭原bai则的核心的思想是软件实体是可扩du展,而不可zhi修改的。 也就是说,对扩展是开dao放的,而对修改是封闭的 新增渠道后,修改代码会产生大量的if else,不太优雅。为了解决以上的两个问题,我们可以借助枚举类来巧妙优化。 % `( S; i0 P8 V7 [) w7 |# B新的思路 1、下面我们调整一下枚举类,增加一个GeneralChannelRule属性,并且给对应渠道构建对应的GeneralChannelRule实现类,新增一个match() 匹配方法。 ) m- G1 j! ?% F6 c" u: E' u$ l public enum ChannelRuleEnum {8 v& P7 q+ S) d5 D, J) d6 z" J /** * 头条 */ TOUTIAO("TOUTIAO",new TouTiaoChannelRule()), /** * 腾讯 */ TENCENT("TENCENT",new TencentChannelRule()),0 L! k: Z: f7 | ? ; 2 M) ]; E4 y7 M: m$ G8 ^) ~ public String name; @, f# S' \, j( C% a, j) x public GeneralChannelRule channel;$ r2 u k* a3 `* G . E7 x0 t5 g# V$ ]8 P. t) e ChannelRuleEnum(String name, GeneralChannelRule channel) {" z' v. ~3 M7 T; m# H7 u this.name = name;/ z, V! U' [% u# g' Q' t8 @; W this.channel = channel; I0 q7 [9 \, b' w } //匹配2 z& f# j) y2 \' I2 Z' ? Q public static ChannelRuleEnum match(String name){ ChannelRuleEnum[] values = ChannelRuleEnum.values(); for (ChannelRuleEnum value : values) { if(value.name.equals(name)){ return value;0 c: T- j7 j- M9 O9 r9 v, {9 y } }6 b8 X2 s/ c5 O/ i& A return null;, z: Y) ]( G! b/ e8 Z# L }5 H) R$ t2 t# z1 } public String getName() {6 M( }2 v( U: r# t1 Y" S& U+ ` return name; }& |5 m3 X# A* ]) E( L1 X% k public GeneralChannelRule getChannel() { return channel; } } % \2 h5 k- K; j) X. ~ : E* S' B& L# @% z" L7 p7 N 2 [1 I6 c h) x. O H: K 2、改写程序 & G: I% ]# w; `+ b* a3 x+ _8 j! Z public static void main(String[] args) {String sign = "TOUTIAO"; ChannelRuleEnum channelRule = ChannelRuleEnum.match(sign);( B6 i+ Q) v1 a! F! ?& I GeneralChannelRule rule = channelRule.channel; rule.process(sign); }- v6 W3 q4 S, E! b 解析:通过使用枚举类,在枚举中将 key 与 规则具体实现进行绑定。通过改变: " S, w1 u# J- q2 f2 P/ Q 可以减少if -else使得代码更加优雅 如果需要新增渠道,我们只需要在编写具体规则实现类并继承GeneralChannelRule抽象类,并在枚举类中新增的枚举,而不需要改动到原先的任何代码。这符合了开发封闭原则。 以上是通过枚举来巧妙干掉if-else的方案,对于减少 if-else 还有很多有趣的解决方案(如:状态设计模式等),感兴趣的朋友去查阅相关的资料。 |
| 学习了 |
微信公众号
手机版