美文网首页程序员的小屋程序员Java 杂谈
设计模式学习笔记(6)工厂方法

设计模式学习笔记(6)工厂方法

作者: 摆码王子 | 来源:发表于2018-05-21 19:36 被阅读3次

本文实例代码:https://github.com/JamesZBL/java_design_patterns

工厂方法(Factory Method)模式,又叫做虚拟构造(Virtual Constructor)模式或多态工厂(Polymorphic Factory)模式。工厂方法的特点是定义一个用于创建对象的接口, 让子类决定实例化哪一个类。 工厂方法使一个类的实例化延迟到其子类。

实例

这次以顾客点餐为例,假设有两个厨师,一个只会做中餐,另一个只会做西餐,餐品分为熟食和生食两类。顾客需要顾客需要根据自己的口味来选择对应的厨师并告知其需要熟食还是生食,厨师根据顾客的口味来进行烹制。

厨师的职责就是烹制食物,所以定义一个厨师接口

Cook.java


public interface Cook {

  Food cookFood(FoodType foodType);

}

现在简单的将食物赋予一个表示“冷或热”的属性,用枚举类型表示

FoodType.java


public enum FoodType {

  HOT("热的"), COLD("凉的");

  private String name;

  FoodType(String foodType) {

    this.name = foodType;

  }

  public String getName() {

    return name;

  }

}

定义食物接口

Food.java


public interface Food {

  FoodType getFoodType();

}

食物有中餐和西餐之分,分别定义两个食物接口的实现类

ChineseFood.java


public class ChineseFood implements Food {

  private FoodType foodType;

  public ChineseFood(FoodType foodType) {

    this.foodType = foodType;

  }

  @Override

  public FoodType getFoodType() {

    return foodType;

  }

  @Override

  public String toString() {

    return foodType.getName() + "中餐";

  }

}

WesternFood.java


public class WesternFood implements Food {

  private FoodType foodType;

  public WesternFood(FoodType foodType) {

    this.foodType = foodType;

  }

  @Override

  public FoodType getFoodType() {

    return foodType;

  }

  @Override

  public String toString() {

    return foodType.getName() + "西餐";

  }

}

中餐厨师和西餐厨师分别烹制中餐和西餐,定义两个厨师接口的实现类

ChineseCook.java


public class ChineseCook implements Cook {

  public Food cookFood(FoodType foodType) {

    return new ChineseFood(foodType);

  }

}

WesternCook.java


public class WesternCook implements Cook {

  public Food cookFood(FoodType foodType) {

    return new WesternFood(foodType);

  }

}

“食物”产品的生产现在交给了“厨师工厂”来实现:


Cook cook1 = new WesternCook();

Cook cook2 = new ChineseCook();

Food food1 = cook1.cookFood(FoodType.COLD);

Food food2 = cook2.cookFood(FoodType.HOT);

本例只是单纯的演示工厂方法,因为对于这几个类而言,显然使用工厂方法模式比直接使用 new 关键字调用构造方法来说要复杂多了,所以简单对象的创建无需引入工厂模式,从而避免给系统带来更高的复杂度。

实际应用

Java 的集合是一套优秀的数据结构设计,大部分集合类型都实现 java.util.Collection 接口,这个接口的父接口 Iterable 接口规定了所有的 Java 集合都必须提供一个 iterator() 方法,返还一个Iterator 类型的对象:

java.lang.Iterable.java


public interface Iterable<E> {

    // ...

    Iterator<E> iterator();

    // ...

}

ArrayList 是我们常用的一个 Collection 接口实现类,其 iterator() 方法实现如下:

java.util.ArrayList.java


public class ArrayList<E> extends AbstractList<E>

        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {

    // ...

    // 返回一个 Iterator 对象,工厂方法的实现

    public Iterator<E> iterator() {

        return new Itr();

    }

    private class Itr implements Iterator<E> {

    // ...

    }

    // ...

}

不难看出,ArrayList 中的 iterator() 方法是具体工厂类的工厂方法,而 Collection 就是一个工厂接口。

总结

在基于类的设计中,工厂方法模式通常作为创建模式来使用。它使用工厂方法来处理创建对象的过程,无需指定创建对象的确切类型。客户端通过调用工厂方法来创建对象,这里的方法是在接口中指定的,或是由子类实现的,或是由基类实现,或者通过子类进行方法覆盖,从头至尾无需调用具体类的构造方法。

工厂方法模式就是为了完全满足“开闭原则”,在上文点餐的例子中,当增加食物类型的时候,无需改动现有的代码,只要增加一个能够完成新类型食物烹饪工作的厨师类即可。

个人博客同步更新,获取更多技术分享请关注:郑保乐的博客

相关文章

  • java/android 设计模式学习笔记(3)---工厂方法模

    java/android 设计模式学习笔记(3)---工厂方法模式 【备注】只用于个人收藏

  • 2021-11-16 - 学习记录

    设计模式学习:创建型:工厂(工厂方法,抽象工厂),建造者,单例,原型 设计模式:工厂模式 简单工厂 工厂方法 抽象工厂

  • 23种设计模式

    完整的学习了设计模式,并且都做了笔记。以下来一个汇总 1、单例模式2、工厂方法模式、抽象工厂模式3、模板方法模式4...

  • Abstract Factory 抽象工厂模式

    设计原则学习笔记 设计模式学习笔记 作用 管理多个系列的产品之间的关系(非必要) 兼具工厂方法的作用 对于作用1...

  • 设计模式学习笔记(6)工厂方法

    本文实例代码:https://github.com/JamesZBL/java_design_patterns 工...

  • 设计模式-抽象工厂模式

    前面我们学习了了简单工厂模式和工厂方法模式,今天我们来学习设计模式中最后的一种工厂模式——抽象工厂模式(Abstr...

  • 设计模式

    说明:以下文字来自《设计模式之禅》的笔记 1、工厂方法模式: 在工厂方法模式中,抽象产品类Product负责定义产...

  • 设计模式之——工厂模式

    前言:本文仅作为第一次学习设计模式的参考和笔记。初探工厂模式&抽象工厂模式: 工厂模式:Factory Patte...

  • java/android 设计模式学习笔记(4)---抽象工厂模

    java/android 设计模式学习笔记(4)---抽象工厂模式 【备注】只用于个人收藏

  • Flyweight 享元模式

    设计原则学习笔记 设计模式学习笔记 作用 提供可复用的对象。 类图 享元模式一般包含一个工厂,工厂中含有一个享元...

网友评论

    本文标题:设计模式学习笔记(6)工厂方法

    本文链接:https://www.haomeiwen.com/subject/sgvqjftx.html