重构之3.Replace Type Code with Subclasses(以子类取代类型码)

场景:

通常我们会在业务层判断类型码,执行不同的方法,可以使用子类来取代类型码

前提:

1.类型码不会被改变

2.类型码所属的类没有子类

修改前:

Student:

/**
 * @file Student.java
 *
 *
 * @author wumingkun
 * @version 1.0.0
 * @Description
 */

package com.refractor.subcode.before;

/**
 * @author wumingkun
 *
 */
public class Student {
	private int id;
	private String name;
	private int type;
	public static final int A =1;
	public static final int B =2;

	public Student(int id, String name, int type) {
		super();
		this.id = id;
		this.name = name;
		this.type = type;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
}

修改后:

Student:

/**
 * @file Student.java
 *
 *
 * @author wumingkun
 * @version 1.0.0
 * @Description
 */

package com.refractor.subcode.after;

/**
 * @author wumingkun
 *
 */
public abstract class Student {
	private int id;
	private String name;
	public static final int A =1;
	public static final int B =2;

	public Student(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	public static Student create(int type){
		switch (type) {
			case A:
				return new TypeA(1,"张三");
			case B:
				return new TypeB(2,"李四");

			default:
				throw new IllegalArgumentException();
		}
	}
	public abstract int getType();
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

}

TypeA:

/**
 *
 * @author wumingkun
 * @version 1.0.0
 * @Description
 */

package com.refractor.subcode.after;

/**
 * @author wumingkun
 *
 */
public class TypeA extends Student {

	/**
	 * @param id
	 * @param name
	 */
	public TypeA(int id, String name) {
		super(id, name);
	}

	/* (non-Javadoc)
	 * @see com.refractor.subcode.after.StudentManagement#getType()
	 */
	@Override
	public int getType() {
		return A;
	}

	@Override
	public String toString() {
		return "TypeA [type=" + getType() + ", id=" + getId()
				+ ", name=" + getName() + "]";
	}

}

TypeB:

/**
 *
 * @author wumingkun
 * @version 1.0.0
 * @Description
 */

package com.refractor.subcode.after;

/**
 * @author wumingkun
 *
 */
public class TypeB extends Student {

	/**
	 * @param id
	 * @param name
	 */
	public TypeB(int id, String name) {
		super(id, name);
	}

	/* (non-Javadoc)
	 * @see com.refractor.subcode.after.StudentManagement#getType()
	 */
	@Override
	public int getType() {
		return B;
	}

}

StudentTest:

/**
 * @file StudentTest.java
 *
 * @author wumingkun
 * @version 1.0.0
 * @Description
 */

package com.refractor.subcode.after;

/**
 * @author wumingkun
 *
 */
public class StudentTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Student student=Student.create(Student.A);
		System.out.println(student);
	}

}
时间: 2024-10-22 21:18:50

重构之3.Replace Type Code with Subclasses(以子类取代类型码)的相关文章

重构之4.Replace Type Code with State/Strategy(以State/Strategy取代类型码)

场景: 你有一个类型码,它会影响类的行为,但你无法通过继承手法来消除它 ,可以使用状态对象取代类型码 类图: 修改前: Student /** * @file Student.java * * * @author wumingkun * @version 1.0.0 * @Description */ package com.demo.refactor.state.before; /** * @author wumingkun * */ public class Student { privat

重构之2.Replace Type Code with Class(以类取代类型码)

场景 在一个类中我们经常会下定义一些类型码,如: public static final int INVALID=0; public static final int VALID=1; 我们可以将这些数值转换为一个类 前提条件: 只有当类型码是纯粹数据时(类型码不会在Switch语句中引起行为的变化时),你才能以类来取代它 修改前代码: Student package com.demo.refactor.codetype.before; public class Student { privat

重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)

所谓的以查询取代临时变量:就是当你的程序以一个临时变量保存某一个表达式的运算效果.将这个表达式提炼到一个独立函数中.将这个临时变量的所有引用点替换为对新函数的调用.此后,新函数就可以被其他函数调用. 例子如下: double basePrice = _quantity*_itemPrice; if (basePrice > 1000) { return basePrice * 0.95; } else { return basePrice * 0.98; } 重构之后代码: if (BasePr

国内如何下载code.google、googlecode上的源码webrtc

Github下载代码确实很方便,直接下载那个zip包就OK,无奈有很多开源代码只在googlecode上有,googlecode又只能通过svn下载.在国内需要翻墙才能下载.本人常用的翻墙手段GoAgent和某某门,GoAgent只能在chrome中用,看看网页:某某门穿透力还是差了点.于是在baidu上有搜索到了一个新方法,成功下载googlecode上的webrtc代码,步骤如下: Step1: 打开https://code.google.com/p/smarthosts/,下载hosts文

.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系.

.NET 中,编译器直接支持的数据类型称为基元类型(primitive type).基元类型和.NET框架类型(FCL)中的类型有直接的映射关系. The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. https://msdn.microsoft.com/zh-cn/library/s

C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析与解决方法

对于C#中异常:“The type initializer to throw an exception(类型初始值设定项引发异常)”的简单分析,目前本人分析两种情况,如下: 情况一: 借鉴麒麟.NET的类型初始值设定项引发异常文章!!!写的很详细,大家可以看一看! 其实麒麟.NET的这篇文章主要讲解分析了静态成员的方面,总的说就是:类型初始化或访问类型的静态成员时,都会对类中的其他静态成员进行初始化,如果有静态构造函数的话,一并执行静态构造函数.在这过程中所引发的异常我就直接借鉴麒麟.NET的例

父类通过泛型获得子类Class类型 以及Type体系

1.背景介绍 在实现SSH框架中,DAO层向数据库持久化的过程中,因为大部分保存对象的方法都会调用到sava():所有索性就把save delete update select 方法进行封装到父类中,这时候就遇到了个问题,子类在调用这些方法的时候,需要根据子类的类型获知子类Class类型:这个时候可以通过传入泛型,根据泛型的类型来获取子类的Class类型:  2.实现代码范例 父类:public abstract class Parents<E> { private Class<?>

【c++错误】类的语法错误 error c2533:constructors not allowed a return type(构造函数不允许返回一个类型)

今天编写类的程序的时候不小心把类后的分号忘写了,就出现上面的错误提示. 顺便复习下类的正确格式: class 类名 { public: //习惯上将公有类型放在前面,便于阅读 ……(外部接口) protected: …… (保护型成员) private: ……(私有成员) }; //这里的分号千万不能忘写,不然会出现错误error: 2533:constructors not allowed a return type

代码重构,空间换时间,dictionary 不要用object ,需明确指定类型

代码重构时,因为修改数据库成本很大,于是,可以在缓存中存储一份期待状态的数据结构: 例如,状态转换: 目标状态,中间件状态,原状态,三个状态之间转换时, 原来的逻辑是:目标状态<--中间件状态<--原状态,可以改为<原状态,中间件状态>-->目标状态, 一般情况下,服务器搭建在虚拟机上时,一般是存储位置大小不再考虑范围之内,cpu的计算能力是共享的,所以一个原则是::用"空间"换"时间",, 貌似: hashtable 和 dictio