- 方法中描述了参数:
1. 构造器重载
重载构造器时,使用描述了参数的静态工厂方法名,这样做的意义何在呢?就在于为动作赋予意义,提升代码的可解释性:
- 传统的实例化方式:
Complex fulcrumPoint = new Complex(23.0);
实例化对象时,显然,new ClassName(param1, param2);并不能为我们提供参数的意义为何。使用描述了参数的静态工厂方法(工厂方法,new 出类实例),其实是对构造函数的进一步封装;
- 解释性更清晰的方式:
Complex fulcrumPoint = Complex.fromRealNumber(23.0);
当然可以考虑将相应的构造器设置为 private,强制这种命名手段。
JDK 实践:
Calendar calendar = Calendar.getInstance();
(当然这里仅仅是为了说明获取类的实例化对象,单例设计模式),本处更想说明的是,构造函数也是一种函数,只是这种函数,并没有指定清晰的含义,尤其是当其参数较多时;
2. switch 的处理:将 switch 语句置于抽象工厂下
public Money calcPay(Employee e) throws InvalidEmployeeType {
switch (e.type) {
case COMMISSIONED:
return calcCommissionedPay(e);
case HOURLY:
return ..;
default:
throw new InvalidEmployeeType(e.type);
}
}
- switch 破坏了单一职责(SRP,Single Responsibility Principe),以及开闭原则(OCP,Open-Closed Principe),当有新的类型适配时,就需对代码做出修改;
- OCP,对扩展是开放的,所谓的扩展,这里指的即是,新的同级的类的添加,以支持新类型的拓展,自然在新添加的类内部有其不一样的实现;
改造:将 switch 语句置于抽象工厂下,而不让任何人看到;
/** * 全体雇员子类的抽象基类,抽象工厂获取类的实例时返回的便是基类(父类引用) */ public abstract class Employee { public abstract boolean isPayday(); public abstract Money calcPay(); public abstract void deliverPay(Money money); } /** * 抽象工厂接口声明 */ public interface EmployeeFactory { public Employee makeEmployee(EmployeeRecord record) throws InvalidEmployeeType; } /** * 抽象工厂的实现类 */ public class EmployeeFactoryImpl implements EmployeeFactory { public Employee makeEmployee(EmployeeRecord record) throws InvalidEmployeeType { switch (record.type) { case ..: return new XXEmployee(); case ...: return new XXEmployee(); default: throw new InvalidEmployeeType(record.type); } } }