简单工厂模式Java

简单工厂模式 属于创建型模式,提供创建对象的最佳方式。通过Java的方式来实现简单工厂模式。简单工厂模式的实质:一个工厂类根据传入的参数,动态决定应该创建哪一类产品类(这些产品类均继承自一个父类或接口)实例。

简单工厂模式问题引入

我们在创建对象的时候,用 new 就行了,那为什么要用函数或类将 new 的过程封装起来呢?

这里,为大家引入两个角色来说明这个问题:一个是类的设计者,一个是类的使用者

类的使用者只关心 “这个对象做这事”、“那个对象做那件事”,而不关心 “这件事如何去做?”,

类的设计者才会去关心 “如何去做”。

举个例子,类的设计者设计了 “阿猫”、“阿狗” 两个类,类的使用者需要创建 “阿猫 1”、“阿狗 2” 两个对象,如果不使用简单工厂模式,类的使用者就需要明确知道 “阿猫”、“阿狗” 两个类,这无疑增加了类使用者的负担。使用工厂来代替创建这两对象,权责分开,比方说,这些动物都有 “吃东西” 的行为,这时,“吃东西” 具体行为是什么样子,这是类的设计者关心的,而何时进行该行为,是类的使用者关心的。

再举个例子,大家经常使用的数据库中间件,无需关心具体的底层实现类,只需将用户名密码等连接信息传过去,就会直接获取到相应的数据库连接实例,这个角度,就可以将数据库中间件看作一个大的工厂。

简单工厂模式优点

一个调用者想创建某个对象,只需知道其名称即可

屏蔽具体行为实现,调用者只需关心产品接口,减轻调用者负担

拓展性高,如果想增加一个产品类,只需拓展一个工厂类即可

简单工厂模式不同实现方式

简单工厂模式分为三种

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

这三种模式从上到下逐步抽象,并且更具有一般性

普通简单工厂模式

普通简单工厂模式就是建立一个具体工厂类,对实现了同一接口的一些类进行实例的创建,首先看下 uml 类图(这里以发送短信、邮件、快递为例):

简单工厂模式Java代码

首先,创建一个三者共有的接口:

public interface Sender {
    public void Send();
}

然后,创建实现类:

public class EmailSender implements Sender{
    @Override
    public void Send() {
        System.out.println("发送邮件");
    }
}
public class SmsSender implements Sender{
    @Override
    public void Send() {
        System.out.println("发送短信");
    }
}

public class ExpressSender implements Sender {
    @Override
    public void Send() {
        System.out.println("发送快递");
    }
}

再然后,我们创建一个工厂类来产出这几种 “产品”:

public class SendFactory {
    public Sender produce(String type) {
        if (type == null) {
            return null;
        } else if ("email".equalsIgnoreCase(type)) {
            return new EmailSender();
        } else if ("sms".equalsIgnoreCase(type)) {
            return new SmsSender();
        } else if ("express".equalsIgnoreCase(type)) {
            return new ExpressSender();
        } else {
            return null;
        }
    }
}

接下来,调用下测试:

public class Main {

    public static void main(String[] args) {
        SendFactory sendFactory = new SendFactory();
        Sender senderSms = sendFactory.produce("sms");
        senderSms.Send(); // 发送短信

        Sender senderEmail = sendFactory.produce("email");
        senderEmail.Send(); // 发送邮件

        Sender senderExpress = sendFactory.produce("express");
        senderExpress.Send(); // 发送快递
    }
}

多方法简单工厂模式

多方法简单工厂是在普通简单工厂模式的基础上该进来的,普通简单工厂模式在使用时,如果 type 类型传递错误则不能正确创建对象,多方法直接将 produce 中的逻辑展开到具体的方法中,从而避免该问题。接下来看下我们的改进:

简单工厂模式Java代码

针对上面代码,我们只需调整 SendFactory 类即可:

public class SendFactory {
    public Sender produceSms(){
        return new SmsSender();
    }

    public Sender produceEmail(){
        return new EmailSender();
    }

    public Sender produceExpress() {
        return new ExpressSender();
    }
}

接下来,我们进行如下简单测试:

public class Main {

    public static void main(String[] args) {
        SendFactory sendFactory = new SendFactory();
        Sender senderEmail = sendFactory.produceEmail();
        senderEmail.Send(); // 发送邮件

        Sender senderSms = sendFactory.produceSms();
        senderSms.Send(); // 发送短信

        Sender senderExpress = sendFactory.produceExpress();
        senderExpress.Send(); // 发送快递
    }
}

静态方法简单工厂模式

普通简单工厂模式和多方法简单工厂模式有一个弊端,就是需要频繁的实例化工厂类,一般我们会将 “多方法” 设置为静态的,从而避免类的频繁实例化,拿来即用。

简单工厂模式Java代码

这里我们直接看修改后的 SendFactory 类:

public class Main {

    public static void main(String[] args) {
        //SendFactory sendFactory = new SendFactory();
        Sender senderEmail = SendFactory.produceEmail();
        senderEmail.Send(); // 发送邮件

        Sender senderSms = SendFactory.produceSms();
        senderSms.Send(); // 发送短信

        Sender senderExpress = SendFactory.produceExpress();
        senderExpress.Send(); // 发送快递
    }
}
赞(3)

评论 1

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    最后一个源码是不是贴错了,应该是SendFactory的源码,把new对象替换为单例或者静态对象。

    小小码农9个月前 (06-03)回复