《重构,改善现有代码的设计》第八章 Duplicate Observed Data
2013-02-26 20:30
239 查看
Java代码
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
/**
* 《重构,改善现有代码的设计》第八章 Duplicate Observed Data
*
* 业务逻辑:
* 一个JFrame(类IntervalWindow)有三个TextField,分别是start,end和length
* 如果你修改Start或End,length就会自动成为两者计算所得的长度
* 如果你修改length,End就会随之改变(start不变)
*
* 主要是使用了Observer模式:
* start,end和length之间的运算,是与具体界面无关的,应该独立出来(成为一个Subject,观察者模式里面的“目标”)
*
* 关键在于解决以下两个问题:
* 1.什么时候计算?当界面上的TextField值有变动时,由WindowObserver调用Subject的set方法
* 2.计算后如何通知界面?Subject调用notifyObservers方法,这个方法会触发WindowObserver的update方法
*
*/
public class ObserveGUIWindow {
public static
void main(String[] args) {
new WindowObserver().init();
}
}
class WindowObserver implements Observer {
private TextField startField;
private TextField endField;
private TextField lengthField;
private Subject subject;
public void init() {
JFrame f = new JFrame("This is a test");
f.setSize(200, 200);
Container content = f.getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());
startField = new TextField("0",
10);
endField = new TextField("0",
10);
lengthField = new TextField("0",
10);
SymFocus listener = new SymFocus();
startField.addFocusListener(listener);
endField.addFocusListener(listener);
lengthField.addFocusListener(listener);
Label startLabel = new Label("start:");
Label endLabel = new Label("end:");
Label lengthLabel = new Label("length:");
content.add(startLabel);
content.add(startField);
content.add(endLabel);
content.add(endField);
content.add(lengthLabel);
content.add(lengthField);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
subject = new Subject();
subject.addObserver(this);
}
//更新界面,最新的值(计算后)来自Subject
public void update(Observable o, Object arg) {
Subject subject = (Subject)o;
startField.setText(subject.getStart());
endField.setText(subject.getEnd());
lengthField.setText(subject.getLength());
}
class SymFocus extends FocusAdapter {
public void focusLost(FocusEvent event) {
Object object = event.getSource();
if (object == startField)
StartFieldFocusLost(event);
else if (object == endField)
EndFieldFocusLost(event);
else if (object == lengthField)
LengthFieldFocusLost(event);
}
}
void StartFieldFocusLost(FocusEvent event) {
//从界面取得输入的值
String start = startField.getText();
subject.setStart(isInteger(start) ? start : "0");
//交由Subject计算
subject.calculateLength();
}
void EndFieldFocusLost(FocusEvent event) {
String end = endField.getText();
subject.setEnd(isInteger(end) ? end : "0");
subject.calculateLength();
}
void LengthFieldFocusLost(FocusEvent event) {
String length = lengthField.getText();
subject.setLength(isInteger(length) ? length : "0");
subject.calculateEnd();
}
boolean isInteger(String str) {
return str != null && str.matches("[0-9]+");
}
}
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
/**
* 《重构,改善现有代码的设计》第八章 Duplicate Observed Data
*
* 业务逻辑:
* 一个JFrame(类IntervalWindow)有三个TextField,分别是start,end和length
* 如果你修改Start或End,length就会自动成为两者计算所得的长度
* 如果你修改length,End就会随之改变(start不变)
*
* 主要是使用了Observer模式:
* start,end和length之间的运算,是与具体界面无关的,应该独立出来(成为一个Subject,观察者模式里面的“目标”)
*
* 关键在于解决以下两个问题:
* 1.什么时候计算?当界面上的TextField值有变动时,由WindowObserver调用Subject的set方法
* 2.计算后如何通知界面?Subject调用notifyObservers方法,这个方法会触发WindowObserver的update方法
*
*/
public class ObserveGUIWindow {
public static
void main(String[] args) {
new WindowObserver().init();
}
}
class WindowObserver implements Observer {
private TextField startField;
private TextField endField;
private TextField lengthField;
private Subject subject;
public void init() {
JFrame f = new JFrame("This is a test");
f.setSize(200, 200);
Container content = f.getContentPane();
content.setBackground(Color.white);
content.setLayout(new FlowLayout());
startField = new TextField("0",
10);
endField = new TextField("0",
10);
lengthField = new TextField("0",
10);
SymFocus listener = new SymFocus();
startField.addFocusListener(listener);
endField.addFocusListener(listener);
lengthField.addFocusListener(listener);
Label startLabel = new Label("start:");
Label endLabel = new Label("end:");
Label lengthLabel = new Label("length:");
content.add(startLabel);
content.add(startField);
content.add(endLabel);
content.add(endField);
content.add(lengthLabel);
content.add(lengthField);
f.setLocationRelativeTo(null);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
subject = new Subject();
subject.addObserver(this);
}
//更新界面,最新的值(计算后)来自Subject
public void update(Observable o, Object arg) {
Subject subject = (Subject)o;
startField.setText(subject.getStart());
endField.setText(subject.getEnd());
lengthField.setText(subject.getLength());
}
class SymFocus extends FocusAdapter {
public void focusLost(FocusEvent event) {
Object object = event.getSource();
if (object == startField)
StartFieldFocusLost(event);
else if (object == endField)
EndFieldFocusLost(event);
else if (object == lengthField)
LengthFieldFocusLost(event);
}
}
void StartFieldFocusLost(FocusEvent event) {
//从界面取得输入的值
String start = startField.getText();
subject.setStart(isInteger(start) ? start : "0");
//交由Subject计算
subject.calculateLength();
}
void EndFieldFocusLost(FocusEvent event) {
String end = endField.getText();
subject.setEnd(isInteger(end) ? end : "0");
subject.calculateLength();
}
void LengthFieldFocusLost(FocusEvent event) {
String length = lengthField.getText();
subject.setLength(isInteger(length) ? length : "0");
subject.calculateEnd();
}
boolean isInteger(String str) {
return str != null && str.matches("[0-9]+");
}
}
相关文章推荐
- 《重构,改善现有代码的设计》第八章 Duplicate Observed Data
- 『重构--改善既有代码的设计』读书笔记---Duplicate Observed Data
- 重构,改善既有代码的设计--第八章感悟
- 『重构--改善既有代码的设计』读书笔记----Replace Data Value with Object
- 《重构——改善现有代码的设计》 读书笔记
- 重构改善既有代码设计--重构手法19:Replace Data Value with Object (以对象取代数据值)
- 『重构--改善既有代码的设计』读书笔记----Introduce Foreign Method
- PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
- 重构-改善既有代码的设计(1)
- 《重构-改善既有代码的设计》读书笔记
- 『重构--改善既有代码的设计』读书笔记----代码坏味道【1】
- 《重构 改善即有代码的设计》笔记
- 重构--改善既有代码的设计:重构原则
- 《重构,改善既有代码的设计》读书笔记
- 《重构:改善代码的既有设计》读书笔记
- 读 《重构 : 改善既有代码的设计》
- 《重构,改善既有代码的设计》读书笔记
- 《重构--改善既有代码的设计》--重构,第一个案例(1)
- 重拾《重构-改善既有代码的设计》
- 重构改善既有代码设计--重构手法01:Extract Method (提炼函数)