標籤:duplicate observed d 複製被監視資料
情境:
如果業務層的內容被內嵌於介面層中,我們需要幫這分離出來
代碼壞味道
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 {@Overridepublic 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;}@Overridepublic 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);}}