• 方法中描述了参数:

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);
            }
        }
    }
posted on 2018-01-16 23:03  未雨愁眸  阅读(177)  评论(0编辑  收藏  举报