重构之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);
	}
}

重构之1.Duplicate Observed Data 复制被监视数据,布布扣,bubuko.com

时间: 2024-07-30 10:13:39

重构之1.Duplicate Observed Data 复制被监视数据的相关文章

『重构--改善既有代码的设计』读书笔记---Duplicate Observed Data

当MVC出现的时候,极大的推动了Model与View分离的潮流.然而对于一些已存在的老系统或者没有维护好的系统,你都会看到当前存在大把的巨大类----将Model,View,Controller都写在了一个widget中.一个分层良好的系统,应该将处理用户界面和处理业务逻辑的代码分开.原因如下 如果你此时需要用不同的用户界面来展示数据,比如微软Excel中的饼状图和折线图,他其实内部展示的数据是一样的,但如果你把这两层用户界面逻辑都放在一个widget中去的话,你就会让这个wiget变得复杂无比

Oracle 11 g duplicate功能_复制dataguard备库

Qracle 11g duplicate功能 不用备份源库,通过网络复制出standby库 1.在standby上grid用户配置listener 注意是指定oracle用户的家目录: 监听状态: [[email protected] ~]$lsnrctl LSNRCTL for Linux:Version 11.2.0.4.0 - Production on 19-MAY-2014 18:46:15 Copyright (c)1991, 2013, Oracle.  All rights re

MongoDB复制集及数据分片详解

前言 MongoDB是一个由C++语言编写的基于分布式文件存储的数据库,是当前NoSQL数据库中比较热门的一种,旨在为Web应用提供可扩展的高性能数据存储解决方案.本文介绍MongoDB复制集及数据分片. MongoDB 简介 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.支持的数据结构非常松散,因此可以存储比较复杂的数据类型.最大的特点是其支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询

R之data.table -melt/dcast(数据合并和拆分)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 30.0px "Helvetica Neue"; color: #323333 } p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px "Helvetica Neue"; color: #323333 } p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px "

使用Data Annotations进行手动数据验证

Data Annotations是在Asp.Net中用于表单验证的 它通过Attribute直接标记字段的有效性,简单且直观.在非Asp.Net程序中(如控制台程序),我们也可以使用Data Annotations进行手动数据验证的,一个简单的例子如下(需要添加System.ComponentModel.DataAnnotations.dll的引用): using System; using System.Collections.Generic; using System.Linq; using

复制粘贴Excel数据列表到StringGrid

复制粘贴Excel数据列表到StringGrid(XE3下编写) 注意引用:Vcl.Clipbrd procedure TDataEditDrFrm.Excel1Click(Sender: TObject);varCopystrings:Tstringlist;daorustring,daorustring1,daorustring2:string;i,j,row1,row2:Integer;begin daorustring:=(Clipboard.AsText); daorustring1:

不同数据库之间复制表的数据的方法

--不同数据库之间复制表的数据的方法: --当表目标表存在时: insert into 目的数据库..表 select * from 源数据库..表 --当目标表不存在时: select * into 目的数据库..表 from 源数据库..表 --如果在不同的SQL之间: insert into openrowset('sqloledb','目的服务器名';'sa';'',目的数据库.dbo.表) select * from 源数据库..表

contentType设置类型导致ajax post data 获取不到数据

ajax post  data  获取不到数据,注意 content-type的设置 .post/get关于 jQuery data 传递数据.网上各种获取不到数据,乱码之类的. 好吧今天我也遇到了,网上一查各种纠结.乱码不管先看获取不到数据. 因为之前一直用jQuery ajax get的方式传递参数, 默认没有设置过 contentType 的值 总结:get方式   这也就是我们说的get方式,参数是跟在url后边,与Content-Type无关. 1 var Skip = 49; //N

Silverlight 2 (beta1)数据操作(3)——使用ADO.NET Data Service (Astoria)进行数据CRUD操作

目录 导言 软件需求 在SQL 2005中创建数据库 在Visual Studio 2008中创建Silverlight工程和ADO.NET Data Service 创建一个XMLHttpRequestWrapper类 在Silverlight中使用Astoria进行CRUD操作 导言 Silverlight 2支持JSON.Web Service.WCF以及Sockets等新特性对数据CRUD操作,这个系列用实例结合数据库一步一步的图文描述来学习一下Silverlight 2 beta 1中