其他分享
首页 > 其他分享> > 设计模式二:工厂模式

设计模式二:工厂模式

作者:互联网

从简单工厂模式到工厂方法模式

从设计模式的类型上来说,简单工厂模式属于创建型模式,又叫作静态工厂模式,但不属于GoF的23种设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,被创建的实例通常都具有共同的父类。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是工厂方法模式和抽象工厂的基础和初步实现。其主要目的是:

  1. 不向客户透露对象实例化的细节
  2. 通过通用接口创建对象

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

简单工厂模式包括如下三种角色:

  1. 简单工厂:负责实现创建所有实例的内部逻辑,具体构造细节是在一个个if/else分支或者switch/case分支里面
  2. 抽象产品:负责描述所有实例所共有的公共接口
  3. 具体产品:简单工厂模式的创建目标

简单工厂模式的UML类图如下:

在这里插入图片描述

下面给出一个例子说明简单工厂模式。

假设有一个蛋糕店,可以生产水果蛋糕、巧克力蛋糕、芝士蛋糕等,只要你提前预定蛋糕的类型,蛋糕店就可以给你生产出来。这里的蛋糕店就是一个简单工厂,水果蛋糕、巧克力蛋糕、芝士蛋糕就是具体产品。

程序代码如下:

/**
* 抽象产品
*/
public interface Cake {  

    void cooking();
    void packing();
}

/**
* 具体产品
*/
public class FruitCake implements Cake {
    @Override
    public void cooking() {
        System.out.println("水果蛋糕制作中...");
    }

    @Override
    public void packing() {
        System.out.println("水果蛋糕打包中...");
    }
}
public class ChocolateCake implements Cake {
    @Override
    public void cooking() {
        System.out.println("巧克力蛋糕制作中...");
    }

    @Override
    public void packing() {
        System.out.println("巧克力蛋糕打包中...");
    }
}
public class CheeseCake implements Cake {
    @Override
    public void cooking() {
        System.out.println("芝士蛋糕制作中...");
    }

    @Override
    public void packing() {
        System.out.println("芝士蛋糕打包中...");
    }
}

/**
* 简单工厂
*/
public class Bakery { 

    public static Cake makeCake(String type) {
        if ("水果".equals(type)) {
            return new FruitCake();
        } else if ("巧克力".equals(type)) {
            return new ChocolateCake();
        } else if ("芝士".equals(type)) {
            return new CheeseCake();
        } else {
            System.out.println("抱歉!蛋糕房无法生产您所需的蛋糕");
            return null;
        }
    }
}

/**
* 测试类
*/
public class FactoryTest {
    public static void main(String[] args) {
        Cake fruitCake = Bakery.makeCake("水果");
        if (fruitCake != null) {
            fruitCake.cooking();
            fruitCake.packing();
        }

        Cake chocolateCake = Bakery.makeCake("巧克力");
        if (chocolateCake != null) {
            chocolateCake.cooking();
            chocolateCake.packing();
        }

        Cake cheeseCake = Bakery.makeCake("芝士");
        if (cheeseCake != null) {
            cheeseCake.cooking();
            cheeseCake.packing();
        }
    }
}

测试结果:

在这里插入图片描述
简单工厂模式具有如下优点:

  1. 简单工厂模式将对象的创建与对象的使用分离,有利于功能的复用和系统的维护
  2. 客户端无需知道所创建的具体产品的类名,只需知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量
  3. 可以通过引入配置文件,可以在不修改任何客户端代码的情况下跟换和增加新的具体产品类,在一定程度上提高了系统的灵活性

缺点:

  1. 工厂类集中了所有产品逻辑,一旦不能工作,整个系统都会收到影响
  2. 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,违背了“开闭原则”

工厂方法模式

工厂方法模式的定义:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中。

工厂方法模式又称为工厂模式,也叫虚拟构造器或者多态工厂模式,属于创建型模式。

工厂方法模式包含的角色如下:

  1. 抽象工厂:将具体工厂的实现隐藏起来,如果具体工厂实现类内部发生变化,对外部客户端的调用没有任何影响。抽象工厂类具有多态性,所以不能实例化,需要根据具体工厂类的不同实现来完成产品对象的创建。
  2. 具体工厂:具体工厂类时依赖于具体的产品的,如果具体产品增加或创建方式改变,只需对具体工厂类做修改,而抽象工厂不需修改。
  3. 抽象产品:抽象产品类向任何发出产品对象创建的客户端屏蔽了产品的细节,而这些细节有具体产品来实现。
  4. 具体产品:具体产品具有产品对象的数据和服务,客户端通过获取所需要的产品对象,来完成特定的业务流程。

工厂方法模式的UML类图如下:

在这里插入图片描述
下面通过一个例子来说明工厂方法模式

OEM制造商可以制造Dell、Sony、Acer和Lenovo等品牌笔记本,如果一次同时生产多个品牌的笔记本的话,有些不利于后期管理,比如加入了新的品牌后,就可能有许多设备上的改动。对此成立了一些子厂,每个子厂只做一种品牌的电脑,而OEM制造商作为核心总部。核心工厂不再负责创建等具体产品,把这些分派给自己的子厂,而核心工厂只需负责制定规范即可。

使用工厂模式模拟笔记本生产的UML类图如下:

在这里插入图片描述

示例代码如下:

1.抽象产品类——Laptop.java

public abstract class Laptop {

    private String brand;

    public Laptop() {
    }

    public Laptop(String brand) {
        this.brand = brand;
    }

    public abstract void printId();

    public void getDescription() {
        System.out.println("电脑品牌:" + this.brand);
    }
}

2.具体实现类——DellLaptop.java、AcerLaptop.java、LenovoLaptop.java

public class DellLaptop extends Laptop {

    private static final String brand = "DELL";
    private static int id;

    public DellLaptop() {
        super(brand);
        id = 1000;
    }

    @Override
    public void printId() {
        System.out.println("序列号:" + id++);
    }
}

public class AcerLaptop extends Laptop {

    private static final String brand = "ACER";
    private static int id;

    public AcerLaptop() {
        super(brand);
        id = 2000;
    }

    @Override
    public void printId() {
        System.out.println("序列号:" + id++);
    }
}

public class LenovoLaptop extends Laptop {

    private static final String brand = "LENOVO";
    private static int id;

    public LenovoLaptop() {
        super(brand);
        id = 3000;
    }

    @Override
    public void printId() {
        System.out.println("序列号:" + id++);
    }
}

3.抽象工厂类——LaptopFactory.java

public interface LaptopFactory {
    Laptop produce();
    void afterSaleService();
}

4.具体工厂类——DellFactory.java、AcerFactory.java、LenovoFactory.java

public class DellFactory implements LaptopFactory {
    @Override
    public Laptop produce() {
        return new DellLaptop();
    }

    @Override
    public void afterSaleService() {
        System.out.println("戴尔售后为您服务!");
    }
}

public class AcerFactory implements LaptopFactory {
    @Override
    public Laptop produce() {
        return new AcerLaptop();
    }

    @Override
    public void afterSaleService() {
        System.out.println("宏基售后为您服务!");
    }
}

ublic class LenovoFactory implements LaptopFactory {
    @Override
    public Laptop produce() {
        return new LenovoLaptop();
    }

    @Override
    public void afterSaleService() {
        System.out.println("联想售后为您服务!");
    }
}

5.测试类

public class FactoryTest {
    public static void main(String[] args) {

        LaptopFactory f1 = new DellFactory();  // 生产两台戴尔电脑
        Laptop p1 = f1.produce();
        Laptop p2 = f1.produce();
        p1.getDescription();
        p1.printId();
        p2.getDescription();
        p2.printId();

        LaptopFactory f2 = new AcerFactory();  // 生产两台宏基电脑
        Laptop p3 = f2.produce();
        Laptop p4 = f2.produce();
        p3.getDescription();
        p3.printId();
        p4.getDescription();
        p4.printId();

        LaptopFactory f3 = new LenovoFactory(); // 生产两台联想电脑
        Laptop p5 = f3.produce();
        Laptop p6 = f3.produce();
        p5.getDescription();
        p5.printId();
        p6.getDescription();
        p6.printId();
    }
}

测试结果:

在这里插入图片描述

标签:void,模式,public,工厂,Override,设计模式,Laptop
来源: https://blog.csdn.net/sun_of_Dec/article/details/113616796