简单工厂模式

介绍

简单工厂模式事实上并不属于23种设计模式中的任何一个模式,但是它的工厂思想是有关工厂的基本思想,这个思想也是非常常用的,了解了它之后我们会对工厂模式有更深的理解

具体实现

工厂角色

ProductApi:生产者API,用于定义生产者的行为规范,即抽象接口

ConcreteProduct:具体的生产者角色,具体已经实现接口的生产者

Factory:工厂,根据参数创建具体的生产者角色

Client:消费者,需要使用具体的某个生产者

代码实现

以程序员的一天为例代码实现

ProductApi类(程序员接口)

public interface Programmer {
    void dayLife();
}

ProductRole(程序员1和程序员2)

public class Programmer1 implements Programmer{

    @Override
    public void dayLife() {
        System.out.println("程序员1:起床-敲代码-吃饭-睡觉");
    }
}
public class Programmer2 implements Programmer{

    @Override
    public void dayLife() {
        System.out.println("程序员2:起床-敲代码-吃饭-陪女朋友逛街-睡觉");
    }
}

Factory(程序员工厂)

public class ProgrammerFactory {
    public Programmer getProgrammer(String type) {
        if ("程序员1".equals(type)) {
            return new Programmer1();
        } else if ("程序员2".equals(type)) {
            return new Programmer2();
        }
        return null;
    }
}

Client(用于测试的消费者1)

public class Client1 {
    public static void main(String[] args) {
        ProgrammerFactory programmerFactory = new ProgrammerFactory();
        Programmer programmer = programmerFactory.getProgrammer("程序员1");
        programmer.dayLife();
    }
}

由代码可以看出工厂类其实就是个生产间,专门负责生产程序员,Client消费端不需要关心自己生产出程序员的细节,消费方只需要传一个参数进去便可取出需要的程序员,那么如果没有工厂类会发生什么呢?

如果把工厂类去掉,那么Client1的代码就会变成这样

public class Client1 {
    public static void main(String[] args) {
        // type一般不是固定的
        String type = "程序员1";
        Programmer programmer = null;
        if ("程序员1".equals(type)) {
            programmer = new Programmer1();
        } else if ("程序员2".equals(type)) {
            programmer = new Programmer2();
        }
        programmer.dayLife();
    }
}

这样如果只有一个Client还好,但是一旦有了Client2、Client3等等,那么每个Client都要写这段代码,首先第一个问题就是代码冗余,再一个一旦这段代码需要更改,那么所有Client都要更改,代价太大了;factory的作用其实就是将所有Client的重复代码合并成一个方法,所有Client都能使用,方法需要更改时只用改factory就完事了,代码既简洁又一定程度上增强了扩展性

代码优化

事实上上述代码还可优化,每次增加一个新的程序员时,factory就需要再加一个else判断,这违反了开闭原则,可使用反射来优化代码

public class ProgrammerFactory {
    public Programmer getProgrammer(Class classs) {
        Programmer programmer = null;
        try {
            programmer = (Programmer) Class.forName(classs.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return programmer;
    }
}
public class Client1 {
    public static void main(String[] args) {
        // 假设此处的arg是外界传入的,且不知道具体是接口的哪个实现类
        Programmer arg = new Programmer1();

        ProgrammerFactory programmerFactory = new ProgrammerFactory();
        Programmer programmer = programmerFactory.getProgrammer(arg.getClass());
        programmer.dayLife();
    }
}

这样不论如何扩展程序员的实现类,factory都能找到对应的实现类也不需要改变代码

【一般参数是个抽象接口,而不是具体的实现类,这是面向接口编程的思想】

优缺点

优点

封装思想:帮助我们实现了组件的封装,然后让组件外部能真正面向接口编程

解耦:通过简单工厂,实现了客户端和具体实现类的解耦。客户端根本就不知道具体是由谁来实现,也不知道具体是如何实现的,客户端只是通过工厂获取它需要的接口对象,一定程度上便于后续扩展

缺点

由于简单工厂是静态工厂,无法形成以继承为体系的工厂结构(此处可看下一篇博客工厂模式)工厂模式

在工厂中违反开闭原则,如果不断地添加新生产者,工厂的生产职责可能越来越复杂,可能有人问这里不是用反射可以优化吗,但不是每个需求都能用反射优化(需求很多总会有不满足的),工厂既承担了程序员1的加工又承担了程序员2的加工,承担了所有程序员的加工过程

使用时机

  • 如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体,那么可以选用简单工厂,让客户端通过工厂来获取相应的接口,而无须关心具体的实现
  • 如果想要把对外创建对象的职责集中管理和控制,可以选用简单工厂,可以把对外创建对象的职责集中到一个简单工厂来,从而实现集中管理和控制

总的来说简单工厂重视封装思想和集中控制管理对象的生命周期

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值