工厂设计模式—java

设计模式不是模板,是在遇到复杂场景的时候,提供一种设计思路。谨记:不要生搬硬套,不要把简单的问题变复杂。

工厂方法模式,在23中设计模式中属于创建型设计模式,简单来说就是只对结果负责,不要三无产品。

在介绍工厂方法方法模式之前,先看下不用设计模式的代码,以牛奶为例,一个销售平台,提供多个牌子的牛奶,客户在购买每种牛奶的时候写法:

Telunsu telunsu=new Telunsu();//特仑苏牛奶
        
Yili yili=new Yili();//伊利牛奶

简单来说,就是客户端要哪种牛奶,我们创建一个(通过new一个对象)。这种方式当然可以解决问题。接下来看下用设计模式的写法和思想。

一. 简单工厂模式

简单工厂模式的思路,先定义一个工厂(一个工厂类),提供一个方法用于创建每个牌子的牛奶,再定义一个牛奶的接口,每种牌子的牛奶都实现这个接口

 
 
public class SimpleFactory {
    
    /**
     * Milk 是一个接口 每种牛奶都实现了这个接口 
     * @param  name 传入牛奶的名字
     * @return 通过判断传入的参数,返回不同牌子的牛奶
     */
    public Milk getMilk(String name){
        if ("telunsu".equals(name)){
            return new Telunsu();
        }
        if ("yili".equals(name)){
            return new Yili();
        }
        return null;
    }
}
 

很好理解,这个方法用于接收客户端想拿到的牛奶的名字,拿到之后这个工厂加以创建并返回给客户端,接着看下客户端的调用过程:

 
SimpleFactory simpleFactory=new SimpleFactory();
Milk telunsu = simpleFactory.getMilk("telunsu");
Milk yili = simpleFactory.getMilk("yili");

 

通过建立一个工厂,并在每个牌子的牛奶上都实现了Milk接口,我们可以通过名字拿到牛奶(也可以通过别的属性,自定义),这样做的好处是客户在拿牛奶的时候看不到生产过程,什么是生产过程,new出来的就是生产过程,因为在实际应用中,创建一个牌子牛奶,往往是很复杂的,简单来说,就是在new的过程中需要进行每个参数的赋值操作,也会有一些别的类的引用,导致客户端只想要一个特仑苏牛奶,我们每次都进行了一大堆操作,这个过程当然也可以进行优化,这里不进行阐述。

 

再实现了简单工厂模式之后,客户端只要告诉工厂我要牛奶的名字即可,创建全部交由这个工厂去实现。

 

二. 工厂方法模式

在实现了简单工厂模式之后,考虑到一个问题,如果要添加一个新牌子的牛奶,这时候,需要在getMilk方法中加一个if语句,这有点违背了设计模式的开闭原则(开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码。)当然在拓展业务的时候,不去修改原有的代码是非常难做到的,但在设计之初,能设计出尽量满足开闭原则的代码是我们要追求的,简单工厂模式还有一个弊端就是客户端需要传入牛奶的名字(也可以是别的),这里是一个字符串,这往往加大程序放生错误的几率。所以工程方法模式出现了。

工厂方法模式就是讲一个简单的工厂,分为多个工厂,在上面的例子中,一个工厂创建了所有牌子的牛奶,其实这是不符合现代化的实际情况的,应该是每种牌子的牛奶都交由一个工厂去生产,也就说想要特仑苏牛奶,通过特仑苏牛奶工厂去创建,想要伊利牛奶,通过伊利牛奶去创建。看下这种模式下的代码:

public interface Factory  {

    Milk getMilk();

}

这里先构造一个工厂接口,就是用来生产牛奶的,生产什么牛奶,由实现这个接口的每个工厂去完成。
 

public class TeFactory implements Factory {

    @Override
    public Milk getMilk() {
        return new Telunsu();
    }
}

特仑苏的工厂实现了工厂接口,并且在getMilk方法里创建特仑苏牛奶,伊利牛奶一样的操作,代码省略。也就是实现一个目的:专人做专事。下面在看下客户端调用的方式:

        // 特仑苏工厂
        Factory teFactory=new TeFactory();
        // 特仑苏工厂生产特仑苏
        Milk telunsu = teFactory.getMilk();
        // 伊利工厂
        Factory yiFactory=new YiFactory();
        // 伊利工厂生产伊利
        Milk yili = yiFactory.getMilk();

这样我们完成了每个工厂生产每种牛奶,同样的,客户端并不会知道我们生产的具体过程。

 

三. 抽象工厂模式

上面介绍了简单工厂和方法工厂,最后介绍下抽象工厂。

抽象工厂模式是在开发中用的比较多的一种工厂设计模式,它可以说是对工厂方法模式的一种改进,在上面的工厂方法模式中,我们生产一种牛奶就要出现一个工厂类,但往往在实际开发中,制作牛奶会有一些相同的标准,我们可以用一个抽象工厂把这些共同的方法提炼出来。抽象工厂还可以减少我们创建的工厂类。看下代码实现:

public abstract class AbstractFactory {

    //公共的逻辑
    //方便于统一管理

    /**
     * 获得一个蒙牛品牌的牛奶
     * @return
     */
    public  abstract Milk getMengniu();

    /**
     * 获得一个伊利品牌的牛奶
     * @return
     */
    public abstract  Milk getYili();
}

定义了一个抽象工厂,抽象工厂里面两个抽象方法分别对应两种品牌的牛奶,抽象工厂面可以有一些公共的逻辑。接着我们去继承这个抽象工厂。

public class MilkFactory extends  AbstractFactory {

    @Override
    public Milk getYili() {
        return new Yili();
    }

    @Override
    public Milk getTelunsu() {
        return new Telunsu();
    }
   
}

到这里就很明了了,我们想要拿到特仑苏或者伊利,只要构造出这个牛奶工厂就可以。

        MilkFactory factory = new MilkFactory();
        Milk telunsu = factory.getSanlu();
        Milk yili = factory.getYili();

抽象工厂的实现,解决了每个工厂生产每个牌子的牛奶(牛奶工厂的每个方法),在需要添加一个新品种的牛奶,我们只要在抽象工厂里面去写一个抽象方法,然后再牛奶工厂实现类里去实现即可,并且抽象工厂里面每个牛奶都可以继承公共方法,加以复用。

上面实现了3种工厂设计模式,客户端不需要知道我们牛奶的创建过程,只要拿到牛奶。工厂设计模式可以说也是在开发中用的比较多的一种,很多的情景都可以用工厂模式。但还是要记住,不要把一个简单的问题变复杂。不要就一个new 可以完成的功能去改写成工厂模式。关于设计模式还是要多思考。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值