简单工厂模式的实现及优缺点

目录

一、开闭原则(Open Close Principle):

二、简单工厂模式的实现:

三、简单工厂模式违反了开闭原则

四、建议


一、开闭原则(Open Close Principle):

  • 定义:

一个软件实体(如类、模块和函数)应该对扩展开放,对修改关闭。

就是说对于一个项目或者某个功能点,现要增加一个新的扩展功能,最好应该在不改变现有代码的前提下,植入新的代码,既不影响现有功能,又能够实现我们新增的功能,并且没有修改现有代码。

个人理解,就好比我现在想喝豆浆,并且只有黄豆,那我就需要一台豆浆机,这个豆浆机暂时把它理解为一个软件实体,突然有一天,欲望膨胀了,我又想和西瓜汁,那么我需要去准备西瓜,但是又不想再买榨汁机,想使用豆浆机来试着榨一杯西瓜汁,那么,在我不对当前的豆浆机做任何改变的前提下,能够榨出一杯西瓜汁,那么原来这台豆浆机,就符合开闭原则;如果我需要对当前豆浆机做出一些零部件的调整,才能和西瓜汁,那么就违反了开闭原则。如果不论怎么改都榨不出西瓜汁,那么就只能喝豆浆(个人意见,若有错误,请评论指出,谢谢

  • 目的

为了代码的可扩展性,并且避免了对现有代码的修改给软件带来风险。

  • 先学习下面的简单工厂模式,之后我们再回来看一下,简单工厂模式是如何违反开闭原则的。

二、简单工厂模式的实现:

  • 定义:定义一个工厂类,根据传入的参数的值不同,返回不同的实例(所有的实例都由仅有的这个工厂来创建)
  • 特点:被创建的实例具有共同的父类或接口
  • 结构:

一个用于创建实例的工厂类

一个接口,所有被创建的实例都要实现该接口

现在想定义一个工厂,用来创建不同的鼠标。上图中,分别定义了 DellMouse 和 HpMouse 且都实现了Mouse接口,同时也都实现了 Mouse 接口中的 sayHi() 方法。又创建了一个叫 MouseFactory 的工厂类,并通过调用该类的 createMouse() 方法,根据传入不同的i值,来决定创建特定类型的鼠标实例,来返回给业务层调用。

比如传入0的时候,就会返回一个DellMouse的实例,并返回。这样,便能在业务需要的时候,调用MouseFactory的静态方法createMouse(),获取我们需要的特定实例,并调用实例的sayHi方法来满足业务需求。

  • 代码实现:

1.首先创建Mouse接口以及DellMouse和HpMouse,并实现sayHi方法:

三个类的具体实现如下:

//Mouse接口
public interface Mouse {
    public void sayHi();
}
//HpMouse类
public class HpMouse implements Mouse {
    @Override
    public void sayHi() {
        System.out.println("我是惠普鼠标");
    }
}
//DellMouse类
public class DellMouse implements Mouse {
    @Override
    public void sayHi() {
        System.out.println("我是戴尔鼠标");
    }
}

2.创建对应的MouseFactory工厂类,用来返回对应的工厂类

具体实现如下:

public class MouseFactory {
    public static Mouse createMouse(int type){
        switch (type){
            case 0 : return new DellMouse();
            case 1 : return new HpMouse();
            default:return new DellMouse();
        }
    }

    public static void main(String[] args) {
        Mouse mouse = MouseFactory.createMouse(1);
        mouse.sayHi();
    }
}

执行main方法,输出如下:

我是惠普鼠标

上面的工厂类,就实现了,根据传入不同的参数,来返回不同的实例。当前例子中,传入1,就返回HpMouse,再通过Mouse接口的sayHi方法,来调用不同实现类的sayHi方法,就实现了简单工厂模式。

在简单工厂中,隐藏了对象创建的细节,客户端不需要自己创建实例,只需要告诉工厂,需要哪个具体实现类就可以。

  • 适用场景:

1.需要创建的对象比较少。

在上面的例子中,我们只是创建了两个鼠标实现类,如果需要几十个上百个具体的实现类的情况,那么在工厂类的switch或者if else语句中就要写很多行代码,很笨重。

2.客户端不关心对象的创建过程

该特点同样适用与其他工厂模式。上面的例子中,就不需要了解DellMouse或者HpMouse实例的创建过程,直接在需要的地方传入不同参数调用就好了。

  • 优缺点:
  • 优点:

可以对创建的对象进行“加工”,对客户端隐藏相关细节。只关注结果,无需了解过程

  • 缺点:

1. 若创建逻辑复杂或创建对象过多,则会造成代码臃肿

2. 新增、删除子类均会违反开闭原则

 

三、简单工厂模式违反了开闭原则

还是上面的鼠标工厂,现在有了新需求,除了DellMouse和HpMouse,我们还需要LenovoMouse,那就需要对现有代码做些调整。

1. 首先新增LenovoMouse的实现类,实现Mouse接口:

public class LenovoMouse implements Mouse {
    @Override
    public void sayHi() {
        System.out.println("我是联想鼠标");
    }
}

仅新增联想鼠标的做法,是符合开闭原则的,毕竟我们只扩展出了一个LenovoMouse的实现类,且没有修改当前代码。

2. 接下来需要修改工厂类MouseFactory,使其能够创建出LenovoMouse的实例

public class MouseFactory {
    public static Mouse createMouse(int type){
        switch (type){
            case 0 : return new DellMouse();
            case 1 : return new HpMouse();
            case 2 : return new LenovoMouse();
            default:return new DellMouse();
        }
    }

    public static void main(String[] args) {
        Mouse mouse = MouseFactory.createMouse(2);
        mouse.sayHi();
    }
}

在工厂中,我们在 switch 语句中添加了一条case, 为了能够让工厂返回LenovoMouse实例。

此时,因为修改了原有工厂类的方法,就违背了开闭原则。

四、建议

所有原则并非一定要严格遵守,而是需要结合业务的实际情况。

上面的例子中,如果我们只需要创建这几个Mouse的实现类,使用简单工厂,违背一下开闭原则也不是不可以。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值