1 重构之重复代码:
2
3 1.(重复代码是)语义一致的逻辑
4 反例:语义一致的逻辑产生了多个实体
5 缺点:如果你为语义一致的逻辑产生了多个实体,那么当需要修改这个逻辑时,你必须保证同时修改所有的实体,并确保它们是一致的。否则,程序就会产生bug。无疑,这么做会额外增加很多的不必要的工作量。
6
7 原则:语义一致的逻辑之应该只产生唯一实体,在需要的地方进行调用。
8
9 反面案例:
10 jdbc操作数据库时,在每个访问方法中写driverClass, url, username, password。
11
12 2.(重复代码是)非语义一致的逻辑。
13 当你的程序中存在多个实体,表示的是非语义一致的逻辑,当修改其中一个不需要维护另一个,因为它们本身就没有语义一致的要求。
14
15 重构之switch语句:
16
17 程序中出现switch语句,就是不好的设计吗?
18
19 一个需要重构的switch语句的案例
20 Movie类
21 priceCode域
22 getCharge(int daysRent):
23 存在switch语句:
24 根据priceCode域的值的不同计算租片费用。
25 其中每个分支中的逻辑的共同点:
26 输入是租期,输出是费用。
27
28 方案:
29 使用状态模式或策略模式对该switch语句进行重构。
30
31 商城案例:根据会员不同的等级,给与不同的折扣,会员等级是变化点
32 会员等级,折扣计算。
33 影片案例:根据影片类型,计算积分和费用(租用时间),影片类型是变化点
34 影片类型,计算积分,计算费用。
35
36
37 静态的方法:
38 charge getCharge(movieType, daysRent){
39 switch(movieType)
40 case x1: xx
41 case x2: xx
42 case x3: xx
43 }
44
45 points getPoints(movieType, daysRent){
46 switch(movieType)
47 case x1: xx
48 case x2: xx
49 case x3: xx
50 }
51 类型作为条件,影响方法的行为。
52
53 满减
54 amount getAmount(amount, customerType){
55 amount > x1
56 xxx
57 amount > x2
58 xxx
59 amount > x3
60 xxx
61
62 switch(customerType)
63 case x1: xx
64 case x2: xx
65 case x3: xx
66 }
67 金额作为条件,影响方法的行为。
68 会员类型作为条件,影响方法的行为。
69
70 满减+打折(大话设计模式中案例)
71
72 amount getAmount(code, amount){
73 switch(code)
74 case 打折x1: xx
75 case 打折x2: xx
76 case 满减x1: xx
77 case 满减x2: xx
78 }
79
80 amount getAmount(amount){
81 switch(code)
82 case 打折x1: cashRebate(折扣)
83 case 打折x2: cashRebate(折扣)
84 case 满减x1: cashReturn(满, 减)
85 case 满减x2: cashReturn(满, 减)
86 }
87 cashRebate(折扣);
88 cashReturn(满, 减);//考虑,满减可能有多对,这时可以用一个数组来表示。
89
90 //可能的过度设计,使用策略模式
91 CashSuper, CashRebate, CashReturn acceptCash()
92
93 Rental中保存daysRent信息,Movie中保存type信息
94
95 程序中有个元素,该元素有限个值,程序中受该元素的值影响的行为。
96 元素是影片类型,并且该影片类型作为条件影响程序的行为是计算费用和计算积分。
97
98
99
100
101 例如,如下场景,switch case分支语句过多:
102
103 /**
104 * 获取地市编码对应的地市名称
105 *
106 * @param cityId 地市编码
107 * @return String 地市名称
108 */
109 public static String getCityName(int cityId) {
110 switch (cityId) {
111 //苏州
112 case GlobalDefine.DATUM_CITY_ID_SZ: {
113 return "sz";
114 }
115 //淮安
116 case GlobalDefine.DATUM_CITY_ID_HA: {
117 return "hz";
118 }
119 //宿迁
120 case GlobalDefine.DATUM_CITY_ID_SQ: {
121 return "sq";
122 }
123 //南京
124 case GlobalDefine.DATUM_CITY_ID_NJ: {
125 return "nj";
126 }
127 //连云港
128 case GlobalDefine.DATUM_CITY_ID_LYG: {
129 return "lyg";
130 }
131 //徐州
132 case GlobalDefine.DATUM_CITY_ID_XZ: {
133 return "xz";
134 }
135 //常州
136 case GlobalDefine.DATUM_CITY_ID_CZ: {
137 return "cz";
138 }
139 //镇江
140 case GlobalDefine.DATUM_CITY_ID_ZJ: {
141 return "zj";
142 }
143 //无锡
144 case GlobalDefine.DATUM_CITY_ID_WX: {
145 return "wx";
146 }
147 //南通
148 case GlobalDefine.DATUM_CITY_ID_NT: {
149 return "nt";
150 }
151 //泰州
152 case GlobalDefine.DATUM_CITY_ID_TZ: {
153 return "tz";
154 }
155 //盐城
156 case GlobalDefine.DATUM_CITY_ID_YC: {
157 return "yc";
158 }
159 //扬州
160 case GlobalDefine.DATUM_CITY_ID_YZ: {
161 return "yz";
162 }
163 //所有地市
164 case GlobalDefine.DATUM_CITY_ALL: {
165 return "all";
166 }
167 default:
168 return "";
169 }
170
171
172
173 使用HashMap来解决switch case 分支语句过多的情况
174
175 /**
176 * 获取地市编码对应的地市名称
177 *
178 * @param cityId 地市编码
179 * @return String 地市名称
180 */
181 public static String getCityName(int cityId) {
182
183 Map<Short, String> cityMap = new HashMap<Short, String>();
184 //苏州
185 cityMap.put(GlobalDefine.DATUM_CITY_ID_SZ, "sz");
186
187 //淮安
188 cityMap.put(GlobalDefine.DATUM_CITY_ID_HA, "ha");
189
190 //宿迁
191 cityMap.put(GlobalDefine.DATUM_CITY_ID_SQ, "sq");
192
193 //南京
194 cityMap.put(GlobalDefine.DATUM_CITY_ID_NJ, "nj");
195
196 //连云港
197 cityMap.put(GlobalDefine.DATUM_CITY_ID_LYG, "lyg");
198
199 //徐州
200 cityMap.put(GlobalDefine.DATUM_CITY_ID_XZ, "xz");
201
202 //常州
203 cityMap.put(GlobalDefine.DATUM_CITY_ID_CZ, "cz");
204
205 //镇江
206 cityMap.put(GlobalDefine.DATUM_CITY_ID_ZJ, "zj");
207
208 //无锡
209 cityMap.put(GlobalDefine.DATUM_CITY_ID_WX, "wx");
210
211 //南通
212 cityMap.put(GlobalDefine.DATUM_CITY_ID_NT, "nt");
213
214 //泰州
215 cityMap.put(GlobalDefine.DATUM_CITY_ID_TZ, "tz");
216
217 //盐城
218 cityMap.put(GlobalDefine.DATUM_CITY_ID_YC, "yc");
219
220 //扬州
221 cityMap.put(GlobalDefine.DATUM_CITY_ID_YZ, "yz");
222
223 //所有地市
224 cityMap.put(GlobalDefine.DATUM_CITY_ALL, "all");
225
226 if (cityMap.containsKey((short) cityId)) {
227 return cityMap.get((short) cityId);
228 } else {
229 return "cityId is error and not find this cityName by cityId";
230 }
231
232
233 public static int getServiceCode(String str){
234 int code = 0;
235 if(str.equals("Age")){
236 code = 1;
237 }else if(str.equals("Address")){
238 code = 2;
239 }else if(str.equals("Name")){
240 code = 3;
241 }else if(str.equals("No")){
242 code = 4;
243 }
244 return code;
245 }
246
247 public static void initialMap(){
248 map.put("Age",1);
249 map.put("Address",2);
250 map.put("Name",3);
251 map.put("No",4);
252 }
253
254