设计模式之工厂模式和抽象工厂

设计模式分类

通常来说设计模式分为三大类:

  • 创建型模式,共 5 种:工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  • 结构型模式,共 7 种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式,共 11 种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

下面用图片来整体描述一下设计模式之间的关系:

设计模式之工厂模式和抽象工厂_第1张图片

工厂模式

工厂模式(Factory Pattern)的意义就跟它的名字一样,在面向对象程序设计中,工厂通常是一个用来创建其他对象的对象。工厂模式根据不同的参数来实现不同的分配方案和创建对象。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。例如用工厂来创建 这个对象,如果我们需要一个男人对象,工厂就会为我们创建一个男人;如果我们需要一个女人,工厂就会为我们生产一个女人。

工厂模式通常分为:

  • 普通工厂模式
  • 多个工厂方法模式
  • 静态工厂方法模式

普通工厂模式

刚刚我们说到,用工厂模式来创建人。先创建一个男人,他每天都“吃饭、睡觉、打豆豆”,然后我们再创建一个女人,她每天也“吃饭、睡觉、打豆豆”。

我们以普通工厂模式为例,在 project 目录下新建一个FactoryTest.java

设计模式之工厂模式和抽象工厂_第2张图片

示例代码如下(下面的代码块中是全部的代码,实际操作中应当按注释创建相应的类再将方法写入对应的类中):

// 二者共同的接口
interface Human{
    public void eat();
    public void sleep();
    public void beat();
}

// 创建实现类 Male
class Male implements Human{
    public void eat(){
        System.out.println("Male can eat.");
    }
    public void sleep(){
        System.out.println("Male can sleep.");
    }
    public void beat(){
        System.out.println("Male can beat.");
    }
}
//创建实现类 Female
class Female implements Human{
    public void eat(){
        System.out.println("Female can eat.");
    }
    public void sleep(){
        System.out.println("Female can sleep.");
    }
    public void beat(){
        System.out.println("Female can beat.");
    }
}

// 创建普通工厂类
class HumanFactory{
    public Human createHuman(String gender){
        if( gender.equals("male") ){
           return new Male();
        }else if( gender.equals("female")){
           return new Female();
        }else {
            System.out.println("请输入正确的类型!");
            return null;
        }
    }
}

// 工厂测试类
public class FactoryTest {
    public static void main(String[] args){
        HumanFactory factory = new HumanFactory();
        Human male = factory.createHuman("male");
        male.eat();
        male.sleep();
        male.beat();
    }
}

打开 terminal,输入命令编译并运行:

javac FactoryTest.java
java FactoryTest

普通工厂模式就是上面那样子了,那么多个工厂方法模式又有什么不同呢?在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象。多个工厂方法模式是提供多个工厂方法,分别创建对象。

多个工厂方法模式

部分示例代码,其他与上面普通工厂模式示例代码一样:

// 多个工厂方法
public class HumanFactory{
    public Male createMale() {
        return new Male();
    }
    public Female createFemale() {
        return new Female();
    }
}

// 工厂测试类
public class FactoryTest {
    public static void main(String[] args){
        HumanFactory factory = new HumanFactory();
        Human male = factory.createMale();
        male.eat();
        male.sleep();
        male.beat();
    }
}

运行结果与普通工厂模式的示例一样。

静态工厂方法模式

将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

部分示例代码:

// 多个工厂方法
public class HumanFactory{
    public static Male createMale() {
        return new Male();
    }
    public static Female createFemale() {
        return new Female();
    }
}

// 工厂测试类
public class FactoryTest {
    public static void main(String[] args){
        Human male = HumanFactory.createMale();
        male.eat();
        male.sleep();
        male.beat();
    }
}

总结:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,所以,大多数情况下,我们会选用第三种——静态工厂方法模式。

抽象工厂

抽象工厂模式(Abstract Factory Pattern)是一种软件开发设计模式。抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。如果比较抽象工厂模式和工厂模式,我们不难发现前者只是在工厂模式之上增加了一层抽象的概念。抽象工厂是一个父类工厂,可以创建其它工厂类。所以我们也叫它 “工厂的工厂”。

“女娲娘娘”只有一个,而我们的工厂却可以有多个,因此在这里用作例子就不合适了。作为“女娲娘娘”生产出来的男人女人们,那就让我们来当一次吃货吧。(吃的东西总可以任性多来一点)

现在,假设我们有 A、B 两个厨房。每个厨房拥有的餐具和食品都不一样,但是用户搭配使用的方式,比如刀子和苹果、杯子和牛奶等等,我们假设是一致的。

设计模式之工厂模式和抽象工厂_第3张图片

抽象工厂模式特别适合于这样的一种产品结构:产品分为几个系列,在每个系列中,产品的布局都是类似的,在一个系列中某个位置的产品,在另一个系列中一定有一个对应的产品。这样的产品结构是存在的,这几个系列中同一位置的产品可能是互斥的,它们是针对不同客户的解决方案,每个客户都只选择其一。

工厂方法模式、抽象工厂模式,傻傻分不清楚。

为了解释得更清楚,先介绍两个概念:

  • 产品等级结构:比如一个抽象类是食物,其子类有苹果、牛奶等等,则抽象食物与具体食物名称之间构成了一个产品等级结构。食物是抽象的父类,而具体的食物名称是其子类。
  • 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。如 AKitchen 生产的苹果、刀子,苹果属于食物产品等级结构中,而刀子则属于餐具产品等级结构中。而 BKitchen 可能生成另一组产品,如牛奶、杯子。

因此工厂方法模式、抽象工厂模式最大的区别在于:

工厂方法模式:针对的是 一个产品等级结构

抽象工厂模式:针对 多个产品等级结构

你可能感兴趣的:(设计模式,java,node.js,设计模式)