二十三天搞懂设计模式之工厂模式

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 二十三天搞懂设计模式之工厂模式

1. 定义

  • 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
  • 单例也是一种工厂
  • 为什么有了new之后,还要有工厂
  • 灵活控制生产过程
  • 权限、修饰、日志

2. 工厂模式

2.1 实现

我们现在有三个交通工具,分别为:飞机、汽车、扫帚,我想要调用任意一个交通工具行驶。

通常简单的实现逻辑如下图所示:


  • 直接让我们的 Main 函数调用相关的类,进行使用
  • 这时候会出现几个问题
  • 我想做一下权限的控制,让 Main 函数根据用户不同,创建类的权限也不同
  • 我不关注你这个类是怎么创建的,我只想通过名称来创建相关的类实例(类似Spring IOC容器)

我们对于这两个问题,来想一下解决方法:


对于权限控制,我们可以创建一个类,在这个类里面进行权限控制,让 Main 方法去调用这个类

对于通过名称创建类,我们也可以创建一个类,让这个类根据不同的名称返回不同的交通工具实例

这样看的话,我们的首要任务就是要添加一个类,这个类能够进行权限控制,也可以进行交通工具类的创建

既然,这个类可以创建交通工具类,我们不仿让该类命名为:VehicleFactory

在这个交通工具工厂里面包含着我们所有的交通工具实例,架构图如下所示

我们只需要 new 一个 SimpleVehicleFactory 类就可以了,通过我们的 SimpleVehicleFactory 类的 getMoveable() 来获取任意的交通工具实例。

我们可以在这个 SimpleVehicleFactory 这个工厂里面书写我们的日志信息、权限信息等

当然,这个也存在一些问题。比如,我们往里添加一个 Train 交通方法时,需要在我们的SimpleVehicleFactory 方法里面再进行添加,这样的话,我们的 SimpleVehicleFactory 的代码会显着比较臃肿,所以,工厂模式也有下面的实现架构图:


  • 对于每一个交通工具,都有一个单独的实现工厂

2.2 第一种方式代码

  • Moveable接口
public interface Moveable {
    public void go();
}

交通工具实现类

  • Car
public class Car implements Moveable {
    public void go() {
        System.out.println("Car go wuwuwuwu...");
    }
}

Plane

public class Plane implements Moveable {
    public void go() {
        System.out.println("Plane go shuashuashua...");
    }
}

Broom

public class Broom implements Moveable{
    public void go() {
        System.out.println("Broom go sousousou...");
    }
}

交通工具工厂:SimpleVehicleFactory

public class SimpleVehicleFactory {
    public Moveable getMoveable(String moveableType) {
        if (moveableType == null) {
            return null;
        }
        if (moveableType.equalsIgnoreCase("Car")) {
            // 权限控制:获取当前登录信息,进行判断
            // 日志打印:logger.debug
            return new Car();
        }
        if (moveableType.equalsIgnoreCase("Plane")) {
            // 权限控制
            // 日志打印:logger.debug
            return new Plane();
        }
        if (moveableType.equalsIgnoreCase("Broom")) {
            // 权限控制
            // 日志打印:logger.debug
            return new Broom();
        }
        return null;
    }
}

测试类

public class Main {
    public static void main(String[] args) {
        SimpleVehicleFactory simpleVehicleFactory = new SimpleVehicleFactory();
        simpleVehicleFactory.getMoveable("Car").go();
        // 结果输出:Car go wuwuwuwu...
    }
}

3. 总结

工厂模式的实现两种各有优点和缺点,需要根据具体的场景和应用去进行使用

当然,这里有一个问题,工厂模式实现的是统一的一类东西,比如:交通工具之间切换、衣服之间切换等等,如果我们现在有一个需求,叫做一键换装

比如:有个人,他拿着AK47、脚踏保时捷、嘴里抽着烟,很是牛逼,不巧,前面就有警察在值班,看见他拿着AK47肯定直接送他进监狱,他现在需要一个功能,一键换装,该怎么实现呢。

下一期的抽象工厂将会解决这个问题。

下期见~

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
设计模式 Rust Java
二十三种设计模式:工厂模式
在上面的示例中,我们定义了一个抽象的产品类 Product,它包含一个抽象的方法 use(),用于表示产品的使用方法。具体的产品类 ProductA 和 ProductB 继承自 Product,并实现了 use() 方法。
82 0
|
设计模式 存储 Rust
二十三种设计模式:单例模式
在这个代码中,我们定义了一个名为Singleton的类,其中包含一个私有的静态指针instance,用于存储单例对象的唯一实例。构造函数被私有化,这意味着外部无法直接实例化Singleton类的对象。我们通过getInstance()方法来获取Singleton类的唯一实例,如果instance指针为空,则创建一个新的Singleton对象并将其赋值给instance指针。最后,我们定义了一个doSomething()方法,用于执行单例类的具体操作。
54 0
|
设计模式 uml
一文搞懂设计模式--简单工厂
一文搞懂设计模式--简单工厂
73 0
|
设计模式 算法
一文搞懂设计模式--工厂方法
一文搞懂设计模式--工厂方法
100 0
|
设计模式 Go
二十三天搞懂设计模式之抽象工厂模式
二十三天搞懂设计模式之抽象工厂模式
二十三天搞懂设计模式之抽象工厂模式
|
设计模式 SQL 缓存
二十三天搞懂设计模式之单例模式的七种写法
二十三天搞懂设计模式之单例模式的七种写法
|
设计模式 消息中间件 算法
面试题(二十五)设计模式
1. 设计模式 1.1 说一说设计模式的六大原则 参考答案 单一职责原则 一个类,应当只有一个引起它变化的原因;即一个类应该只有一个职责。 就一个类而言,应该只专注于做一件事和仅有一个引起变化的原因,这就是所谓的单一职责原则。该原则提出了对对象职责的一种理想期望,对象不应该承担太多职责,正如人不应该一心分为二用。唯有专注,才能保证对象的高内聚;唯有单一,才能保证对象的细粒度。对象的高内聚与细粒度有利于对象的重用。一个庞大的对象承担了太多的职责,当客户端需要该对象的某一个职责时,就不得不将所有的职责都包含进来,从而造成冗余代码。 里氏替换原则 在面向对象的语言中,继承是必不可少的、优秀的语言机制
101 0
|
设计模式 Java
设计模式轻松学【十七】原型模式
在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效。就像孙悟空拔下猴毛轻轻一吹就变出很多孙悟空一样简单。
148 0
设计模式轻松学【十七】原型模式
|
设计模式 算法
二十三种设计模式
二十三种设计模式
|
设计模式
二十三种设计模式 之 初识设计模式
二十三种设计模式 之 初识设计模式
146 0