创建型设计模式----简单工厂模式

1.含义

  • 简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
  • 现实生活中,工厂是负责生产产品的;同样在设计模式中,简单工厂模式我们可以理解为负责生产对象的一个类,称为“工厂类”。

2. 解决的问题

将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。

即使用者可直接消费产品而不需要知道其生产的细节

3. 模式原理


3.1 模式组成

组成(角色) 关系 作用
抽象产品(Product) 具体产品的父类 描述产品的公共接口
具体产品(Concrete Product) 抽象产品的子类;工厂类的创建目标 描述生产的具体产品
工厂(Factory) 被外界调用

根据传入不同的参数从而创建不同

具体产品类的实例


3.2 UML类图

3.3 使用步骤

  • 创建抽象产品类 & 定义具体产品的公共接口;
  • 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
  • 创建工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
  • 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例

4. 实例

4.1 实例概况

  • 背景:小成有一个塑料生产厂,用来做塑料加工生意
  • 目的:最近推出了3个产品,小成希望使用简单工厂模式实现3款产品的生产

4.2 使用步骤

实现代码如下:

步骤1. 创建抽象产品类,定义具体产品的公共接口

abstract class Product{
    public abstract void Show();
}

步骤2. 创建具体产品类(继承抽象产品类),定义生产的具体产品


//具体产品类A
class  ProductA extends  Product{

    @Override
    public void Show() {
        System.out.println("生产出了产品A");
    }
}

//具体产品类B
class  ProductB extends  Product{

    @Override
    public void Show() {
        System.out.println("生产出了产品B");
    }
}

//具体产品类C
class  ProductC extends  Product{

    @Override
    public void Show() {
        System.out.println("生产出了产品C");
    }
}

步骤3. 创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例

class  Factory {
    public static Product Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
        switch (ProductName){
            case "A":
                return new ProductA();

            case "B":
                return new ProductB();

            case "C":
                return new ProductC();

            default:
                return null;

        }
    }
}

步骤4. 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例

//工厂产品生产流程
public class SimpleFactoryPattern {
    public static void main(String[] args){
        Factory mFactory = new Factory();

        //客户要产品A
        try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
            mFactory.Manufacture("A").Show();
        }catch (NullPointerException e){
            System.out.println("没有这一类产品");
        }

        //客户要产品B
        try {
            mFactory.Manufacture("B").Show();
        }catch (NullPointerException e){
            System.out.println("没有这一类产品");
        }

        //客户要产品C
        try {
            mFactory.Manufacture("C").Show();
        }catch (NullPointerException e){
            System.out.println("没有这一类产品");
        }

        //客户要产品D
        try {
            mFactory.Manufacture("D").Show();
        }catch (NullPointerException e){
            System.out.println("没有这一类产品");
        }
    }
}

实验题:

1. 使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数“M”,则返回一个Man对象,如果传入参数“W”,则返回一个Woman对象,用Java语言实现该场景。现需要增加一个新的Robot类,如果传入参数“R”,则返回一个Robot对象,对代码进行修改并注意“女娲”的变化。

(1)为未增加Robot类的时候,代码如下

//抽象人类
abstract class People {
  public abstract void Make();
}
//Man类实现人类
class  Man extends  People{

  public void Make() {
      System.out.println("产生了Man对象");
  }
}
//Wowan类具体实现人类
class  Wowan extends  People{

  public void Make() {
      System.out.println("产生了Wowan对象");
  }
}
//创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例
class  Factory {
  public static People Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
      switch (ProductName){
          case "M":
              return new Man();

          case "W":
              return new Wowan();

          default:
              return null;

      }
  }
}
//工厂产品生产流程
public class SimpleFactoryPattern {
  public static void main(String[] args){
      Factory mFactory = new Factory();

      //生产Man类
      try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
          mFactory.Manufacture("M").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }

      //生产Women类
      try {
          mFactory.Manufacture("W").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }

      //客户要其他类
      try {
          mFactory.Manufacture("D").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }
  }
}

 (2)增加Robot类的时候,代码如下

//抽象人类
abstract class People {
  public abstract void Make();
}
//Man类实现人类
class  Man extends  People{

  public void Make() {
      System.out.println("产生了Man对象");
  }
}
//Wowan类具体实现人类
class  Wowan extends  People{

  public void Make() {
      System.out.println("产生了Wowan对象");
  }
}
//Man类实现人类
class  Root extends  People{

public void Make() {
    System.out.println("产生了Root对象");
}
}
//创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例
class  Factory {
  public static People Manufacture(String ProductName){
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
      switch (ProductName){
          case "M":
              return new Man();

          case "W":
              return new Wowan();
              
          case "R":
              return new Root();

          default:
              return null;

      }
  }
}
//工厂产品生产流程
public class SimpleFactoryPattern {
  public static void main(String[] args){
      Factory mFactory = new Factory();

      //生产Man类
      try {
//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
          mFactory.Manufacture("M").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }

      //生产Women类
      try {
          mFactory.Manufacture("W").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }

      //生产Root类
      try {
          mFactory.Manufacture("R").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }
      //客户要其他类
      try {
          mFactory.Manufacture("D").Make();
      }catch (NullPointerException e){
          System.out.println("没有这一类产品");
      }
  }
}

可以看出,当我们需要增加新类型的人类时,不仅需要新增加一个新类型类,还需要对“女娲”即工厂类进行修改。

5. 优点


  将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。


6. 缺点


 (1)工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
(2)违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
(3)简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。


7. 应用场景

(1)客户如果只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时;
(2)当工厂类负责创建的对象(具体产品)比较少时。
 

猜你喜欢

转载自blog.csdn.net/h18377528386/article/details/125105058
今日推荐