首页 > 代码库 > 重构之1.Duplicate Observed Data 复制被监视数据

重构之1.Duplicate Observed Data 复制被监视数据

场景:


如果业务层的内容被内嵌于界面层中,我们需要帮这分离出来


代码坏味道


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);
	}
}