Day 05: Creational patterns - Simple Factory Method

目的

传入参数後,藉由 switch-case 来建立一系列拥有相同亲代的物件

说明

作为入门 Design Pattern 的第一个模式,Simple Factory Method 本身不属於「物件导向设计模式」所列的 23 个模式内,其价值在於了解「简单」、「常用」的写法也属於设计模式的一种。

Simple Factory Method 的作法是:

  1. 先决定要建立的物件,该物件视为亲代,可以用 Class、Abstract Class 或 Interface。
  2. 建立一系列的子代物件,子代负责实作细节。
  3. 建立工厂,藉由传入的参数搭配 switch-case 後决定生产哪个物件。

UML 图

Simple Factory Method UML Diagram

使用 Java 实作

产品亲代:PETBottle

public abstract class PETBottle {
    protected String smell = "";
    protected String color = "";

    public void setBottle(String smell, String color) {
        this.smell = smell;
        this.color = color;
    }

    public abstract String getTaste();
}

产品子代:CokeWaterOrangeJuice

public class Coke extends PETBottle {
    @Override
    public String getTaste() {
        return "这瓶可乐的颜色:" + color + ",香味是:" + smell;
    }
}

public class Water extends PETBottle {
    @Override
    public String getTaste() {
        return "这瓶水的颜色:" + color + ",香味是:" + smell;
    }
}

public class OrangeJuice extends PETBottle {
    @Override
    public String getTaste() {
        return "这瓶柳橙汁的颜色:" + color + ",香味是:" + smell;
    }
}

工厂:PETBottleFactory

public class PETBottleFactory {
    public static PETBottle getPETBottle(String option) throws Exception {
        PETBottle bottle = null;

        switch (option) {
            case "coke":
                bottle = new Coke();
                break;
            case "Water":
                bottle = new Water();
                break;
            case "OrangeJuice":
                bottle = new OrangeJuice();
                break;
            default:
                throw new Exception("输入错误");
        }

        return bottle;
    }
}

实作:

public class PETBottleSimpleFactorySample {
    public static void main(String[] args) throws Exception {
        String option = "coke";
        String smell = "甜甜的";
        String color = "黑黑的";
        PETBottle bottle = PETBottleFactory.getPETBottle(option);
        bottle.setBottle(smell, color);
        System.out.println(bottle.getTaste());
    }
}

使用 JavaScript 实作

受限於 JavaScript 没有虚拟型别、无法限制型别。

产品亲代:PETBottle

/** @abstract */
class PETBottle {
  constructor() {
    this.smell = '';
    this.color = '';
  }

  setBottle(smell, color) {
    this.smell = smell;
    this.color = color;
  }

  getTaste() { return; }
}

产品子代:CokeWaterOrangeJuice

class Coke extends PETBottle {
  /** @override */
  getTaste() {
    return "这瓶可乐的颜色:" + this.color + ",香味是:" + this.smell;
  }
}

class Water extends PETBottle {
  /** @override */
  getTaste() {
    return "这瓶水的颜色:" + this.color + ",香味是:" + this.smell;
  }
}

class OrangeJuice extends PETBottle {
  /** @override */
  getTaste() {
    return "这瓶柳橙汁的颜色:" + this.color + ",香味是:" + this.smell;
  }
}

工厂:PETBottleFactory

class PETBottleFactory {
  static getPETBottle(option) {
    /** @type PETBottle */
    let bottle = null;

    switch (option) {
      case "coke":
        bottle = new Coke();
        break;
      case "Water":
        bottle = new Water();
        break;
      case "OrangeJuice":
        bottle = new OrangeJuice();
        break;
      default:
        throw new Error("输入错误");
    }

    return bottle;
  }
}

实作:

const PETBottleSimpleFactorySample = () => {
  const option = "coke";
  const smell = "甜甜的";
  const color = "黑黑的";
  const bottle = PETBottleFactory.getPETBottle(option);
  bottle.setBottle(smell, color);
  console.log(bottle.getTaste());
};

PETBottleSimpleFactorySample();

总结

Simple Factory Method 最适合当作第一个入门的模式,在於简单好懂:

  • 当需要产生相同类型的「服务」时,可以先建立一个亲代,再建立一堆子代,最後用一个生产者物件负责生产。
  • 使用时,将参数交给生产者物件即可决定要使用哪个子代。

缺点则是要增加子代项目时,必须修改「生产者物件」,也就是 switch 的区块,这点会破坏 SOLIDOCP,每次修改程序码时,不该动到既有的程序码。

因为这一点,才有後续两个与 Factory 有关的模式。


<<:  Day 5 安装Prometheus

>>:  20.移转 Aras PLM大小事-自制快速新增专案工作产出文件

Day.8 Reverse Linked List

Leetcode #206. Reverse Linked List 简单来说这一题要做反转链结 e...

JavaScript Day 4. ParseInt / ToString

ParseInt() 直到我在写这篇之前,parseInt 在我心中都还是一个很简单的概念,一个可以...

Day17 CSS Media Query

在了解Media Queries的用法之前,先来了解一些RWD的观念吧。 RWD是什麽? RWD是...

英文能力重要吗?

过去有份工作,在刚进入公司时,在公司内部用不到英文,但是随着组织异动,与外国客户以及跨国团队沟通。而...

javascript基础功能2

现在要来学习如何制作一个表格,并且对其文字粗细加工,还有边框的变换以及表格的样式改变。 首先我们先打...