大话设计模式阅读摘要(一)-简单工厂模式

158 阅读2分钟

活字印刷

背景

古代印刷术就是把文章内容刻在石头或者木板上,每次修改内容,我们需要重新刻画,原来的那块也就废弃了,这种方式很浪费人力物力。后来慢慢出现了活字印刷术,人们只需要预先把所有的文字刻画好,然后拼在一起就行成文章,每个字都不浪费,大大节省了物力人工。

优势

  • 可维护:文章内容变更,只需要替换对应的文字即可
  • 可复用:多余的文字不是完全浪费,可在之后的刻画中使用
  • 可拓展:若文章要加字,只需要重新刻画那个字即可
  • 灵活性好:支持横排/竖排,灵活性好

简单工厂模式

野生代码

直接用if-else这种写死的方法编写工资计算模块,每次修改必须修改原先运行稳定的代码,耦合性高,风险大。(印刷术)

优化代码

在抽象父类中定义好功能,利用子类实现具体各个工种的薪资计算,松耦合,可拓展。(活字印刷术)

  • 常量类
package com.design.design.simpleFactory;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:32
 */
public class Constant {
  public static final int JAVA_SALARY_INCENTIVE = 10;
  public static final int PHP_SALARY_INCENTIVE = 1;
}

  • 对象
package com.design.design.simpleFactory;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;

import java.math.BigDecimal;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:17
 */
@Data
@Builder
@AllArgsConstructor
@RequiredArgsConstructor
public class Salary {
    private int day;
    private BigDecimal datPay;
}

  • 抽象父类
package com.design.design.simpleFactory;

import java.math.BigDecimal;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:12
 */
public abstract class BaseSalaryCalculation {
  /**
   * 计算月薪
   * @param salary 计费对象
   */
  public abstract BigDecimal getSalary(Salary salary);
}

  • JAVA子类
package com.design.design.simpleFactory;

import java.math.BigDecimal;

import static com.design.design.simpleFactory.Constant.JAVA_SALARY_INCENTIVE;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:14
 */
public class JavaSalaryCalculation extends BaseSalaryCalculation {

  /**
   * JAVA激励10天
   *
   * @param salary 计费对象
   * @return 月薪
   */
  @Override
  public BigDecimal getSalary(Salary salary) {
    return salary.getDatPay().multiply(new BigDecimal(salary.getDay() + JAVA_SALARY_INCENTIVE));
  }
}

  • PHP子类
package com.design.design.simpleFactory;

import java.math.BigDecimal;

import static com.design.design.simpleFactory.Constant.PHP_SALARY_INCENTIVE;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:15
 */
public class PHPSalaryCalculation extends BaseSalaryCalculation {

  /**
   * PHP激励1天
   *
   * @param salary 计费对象
   * @return 月薪
   */
  @Override
  public BigDecimal getSalary(Salary salary) {
    return salary.getDatPay().multiply(new BigDecimal(salary.getDay() + PHP_SALARY_INCENTIVE));
  }
}

  • 工厂类
package com.design.design.simpleFactory;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:22
 */
public class SalarySimpleFactory {
  public static BaseSalaryCalculation getSalaryCalculation(Class c) {
    BaseSalaryCalculation baseSalaryCalculation = null;
    try {
      baseSalaryCalculation = (BaseSalaryCalculation) Class.forName(c.getName()).newInstance();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return baseSalaryCalculation;
  }
}

  • 测试
package com.design.design.simpleFactory;

import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;

/**
 * @author zhaozha
 * @date 2019/11/3 上午9:33
 */
@Slf4j
public class Test {
  public static void main(String agrs[]) {
    BaseSalaryCalculation javaSalaryCalculation =
        SalarySimpleFactory.getSalaryCalculation(JavaSalaryCalculation.class);
    final Salary salary = Salary.builder().day(20).datPay(new BigDecimal("300.20")).build();
    log.info("JAVA月薪:{}", javaSalaryCalculation.getSalary(salary));
    BaseSalaryCalculation phpSalaryCalculation =
        SalarySimpleFactory.getSalaryCalculation(PHPSalaryCalculation.class);
    log.info("PHP月薪:{}", phpSalaryCalculation.getSalary(salary));
  }
}

  • 测试结果