场景:
如果业务层的内容被内嵌于界面层中,我们需要帮这分离出来
代码坏味道
MyFrame
/** * * @author wumingkun * @version 1.0.0 * @Description */ package com.demo.refactor; import java.util.Observable; import java.util.Observer; /** * @author wumingkun * */ public class MyFrame { private MyText beginField; private MyText endField; private MyText lengthField; public MyFrame(MyText beginField, MyText endField, MyText lengthField) { this.beginField = beginField; this.endField = endField; this.lengthField = lengthField; } /** * 开始值发生变化 */ private void beginChange() { calculateLength(); } /** * 结束值发生变化 */ private void endChange() { calculateLength(); } /** * 长度发生变化 */ private void lengthChange() { calculateEnd(); } public void onchange(int type) { if (type == 1) { beginChange(); } else if (type == 2) { endChange(); } else { lengthChange(); } } /** * 计算结束的值 */ private void calculateEnd() { int begin=Integer.parseInt(this.beginField.getText()); int length=Integer.parseInt(this.lengthField.getText()); int end=length+begin; this.endField.setText(String.valueOf(end)); } /** *计算长度的值 */ private void calculateLength() { int begin=Integer.parseInt(this.beginField.getText()); int end=Integer.parseInt(this.endField.getText()); int length=end-begin; lengthField.setText(String.valueOf(length)); } }
这个类中calculateEnd及calculateLength两个方法,属于业务逻辑层的内容,它不该位于界面类当中
重构手段:
1.引入观察者模式
2.利用Move Method将calculateEnd及calculateLength移到新类中
3.建立委托关系
重构后代码:
MyFrame
/** * * @author wumingkun * @version 1.0.0 * @Description */ package com.demo.refactor; import java.util.Observable; import java.util.Observer; /** * @author wumingkun * */ public class MyFrame implements Observer { @Override public void update(Observable o, Object arg) { this.beginField.setText(subject.getBegin()); this.endField.setText(subject.getEnd()); this.lengthField.setText(subject.getLength()); } private MyText beginField; private MyText endField; private MyText lengthField; Interval subject; public MyFrame(MyText beginField, MyText endField, MyText lengthField) { super(); this.beginField = beginField; this.endField = endField; this.lengthField = lengthField; subject = new Interval(this.beginField.getText(), this.endField.getText(), this.lengthField.getText()); subject.addObserver(this); } /** * */ private void baginLost() { setBegin(beginField.getText()); } /** * */ private void endLost() { setEnd(endField.getText()); } /** * */ private void lengthLost() { setLength(lengthField.getText()); } public void onchange(int type) { if (type == 1) { baginLost(); } else if (type == 2) { endLost(); } else { lengthLost(); } } public String getBegin() { return this.subject.getBegin(); } public void setBegin(String begin) { this.subject.setBegin(begin); } public String getEnd() { return this.subject.getEnd(); } public void setEnd(String end) { this.subject.setEnd(end); } public String getLength() { return this.subject.getLength(); } public void setLength(String length) { this.subject.setLength(length); } }
Interval
/** * @author wumingkun * @version 1.0.0 * @Description */ package com.demo.refactor; import java.util.Observable; import java.util.Observer; /** * @author wumingkun * */ public class Interval extends Observable { private String begin; private String end; private String length; public Interval(String begin, String end, String length) { super(); this.begin = begin; this.end = end; this.length = length; } @Override public synchronized void addObserver(Observer o) { super.addObserver(o); } public String getBegin() { return begin; } public void setBegin(String begin) { this.begin = begin; change(1); } public String getEnd() { return end; } public void setEnd(String end) { this.end = end; change(1); } public String getLength() { return length; } public void setLength(String length) { this.length = length; change(2); } private void change(int type) { if(type==1){ calculateLength(); }else { calculateEnd(); } super.setChanged(); super.notifyObservers(); } /** * */ private void calculateEnd() { int begin=Integer.parseInt(this.begin); int length=Integer.parseInt(this.length); int end=length+begin; this.end=String.valueOf(end); } /** * */ private void calculateLength() { int begin=Integer.parseInt(this.begin); int end=Integer.parseInt(this.end); int length=end-begin; this.length=String.valueOf(length); } }