大话设计模式-工厂模式

1.简单工厂

实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果。

// 抽象产品:计算抽象类
  public static abstract class Operation {
    protected double a;
    protected double b;

    abstract double getResult();
  }

  // 具体产品:加法操作
  public static class OperationAdd extends Operation {
    @Override
    public double getResult() {
      return a + b;
    }
  }

  // 具体产品:减法操作
  public static class OperationSub extends Operation {
    @Override
    public double getResult() {
      return a - b;
    }
  }

  // 具体产品:乘法操作
  public static class OperationDiv extends Operation {
    @Override
    public double getResult() {
      if (b == 0) throw new RuntimeException("被除数不能为0");
      return a / b;
    }
  }

  // 具体产品:减法操作
  public static class OperationMul extends Operation {
    @Override
    public double getResult() {
      return a * b;
    }
  }

  // 简单工厂
  public static class OperationFactory {
    public static Operation createOperation(String operator) {
      Operation operation = null;
      switch (operator) {
        case "+":
          operation = new OperationAdd();
          break;
        case "-":
          operation = new OperationSub();
          break;
        case "*":
          operation = new OperationMul();
          break;
        case "/":
          operation = new OperationDiv();
          break;
      }
      if (operation == null) {
        throw new RuntimeException(String.format("不支持的操作符[%s]", operator));
      }
      return operation;
    }
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入数字A:");
    String a = sc.nextLine();
    System.out.println("请选择运算符号(+、-、*、/):");
    String operator = sc.nextLine();
    Operation operation = OperationFactory.createOperation(operator);
    System.out.println("请输入数字B:");
    String b = sc.nextLine();
    operation.a = Double.parseDouble(a);
    operation.b = Double.parseDouble(b);
    System.out.println("计算结果:" + operation.getResult());
  }

简单工厂模式的优点:

  • 工厂类含有必要的创建何种产品的逻辑,这样客户端只需要请求需要的产品,而不需要理会产品的实现细节。

简单工厂模式的缺点:

  • 工厂类只有一个,它集中了所有产品创建的逻辑,它将是整个系统的瓶颈,同时造成系统难以拓展。
  • 简单工厂模式通常使用静态工厂方法,这使得工厂类无法由子类继承,这使得工厂角色无法形成基于继承的等级结构。

2.工厂方法

// 抽象产品:计算抽象类
  public static abstract class Operation {
    protected double a;
    protected double b;

    abstract double getResult();
  }

  // 具体产品:加法操作
  public static class OperationAdd extends Operation {
    @Override
    public double getResult() {
      return a + b;
    }
  }

  // 具体产品:减法操作
  public static class OperationSub extends Operation {
    @Override
    public double getResult() {
      return a - b;
    }
  }

  // 工厂方法
  public static abstract class OperationFactory {
    public abstract Operation createOperation();
  }

  public static class OperationFactoryAdd extends OperationFactory {
    @Override
    public Operation createOperation() {
      return new OperationAdd();
    }
  }


  public static class OperationFactorySub extends OperationFactory {
    @Override
    public Operation createOperation() {
      return new OperationSub();
    }
  }

  public static OperationFactory createFactory(String operator) {
    OperationFactory of = null;
    switch (operator) {
      case "+":
        of = new OperationFactoryAdd();
        break;
      case "-":
        of = new OperationFactorySub();
        break;
    }
    if (of == null) {
      throw new RuntimeException(String.format("不支持的操作符[%s]", operator));
    }
    return of;
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入数字A:");
    String a = sc.nextLine();
    System.out.println("请选择运算符号(+、-):");
    String operator = sc.nextLine();
    OperationFactory of = createFactory(operator);
    Operation operation = of.createOperation();
    System.out.println("请输入数字B:");
    String b = sc.nextLine();
    operation.a = Double.parseDouble(a);
    operation.b = Double.parseDouble(b);
    System.out.println("计算结果:" + operation.getResult());
  }

工厂方法的优缺点:

  • 降低了工厂类的内聚,满足了类之间的层次关系,又很好的符合了面向对象设计中的单一职责原则,这样有利于程序的拓展
  • 需要一个新的产品的时候,只需要添加一个新产品及对应工厂即可。

3.抽象工厂

// 抽象产品:计算抽象类
  public static abstract class Operation {
    protected double a;
    protected double b;

    abstract double getResult();
  }

  // 具体产品:加法操作
  public static class OperationAdd extends Operation {
    @Override
    public double getResult() {
      return a + b;
    }
  }

  // 具体产品:减法操作
  public static class OperationSub extends Operation {
    @Override
    public double getResult() {
      return a - b;
    }
  }

  // 工厂方法
  public static abstract class OperationFactory {
    public abstract Operation createOperation();
  }

  public static class OperationFactoryAdd extends OperationFactory {
    @Override
    public Operation createOperation() {
      return new OperationAdd();
    }
  }


  public static class OperationFactorySub extends OperationFactory {
    @Override
    public Operation createOperation() {
      return new OperationSub();
    }
  }


  private static final Map switchMap = new HashMap<>();

  static {
    switchMap.put("+", OperationFactoryAdd.class);
    switchMap.put("-", OperationFactorySub.class);
  }

  public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
    Scanner sc = new Scanner(System.in);
    System.out.println("请输入数字A:");
    String a = sc.nextLine();
    System.out.println("请选择运算符号(+、-):");
    String operator = sc.nextLine();
    OperationFactory of = (OperationFactory) switchMap.get(operator).newInstance();
    Operation operation = of.createOperation();
    System.out.println("请输入数字B:");
    String b = sc.nextLine();
    operation.a = Double.parseDouble(a);
    operation.b = Double.parseDouble(b);
    System.out.println("计算结果:" + operation.getResult());
  }

为创建一组相关或相互依赖的对象提供一个接口,而无需指定他们的具体类。
采用反射机制和Map集合去除繁重的switch操作。
抽象工厂的例子:Java jdbc驱动的实现

你可能感兴趣的:(大话设计模式-工厂模式)