欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式第四篇-工厂模式

程序员文章站 2022-05-04 13:31:31
一、引言 园子里有关设计模式的文章可以说数不胜数,之前也看过很多,但是其实理解都不深入,时间一长就忘了。最好是记录下来,总结中加深印象,这里也给刚开始进行开发的同学提个建议,不要因为自己写的不好而不去写,谁都是从菜鸟开始的,不断的总结才能将知识消化成自己的。 现在开始今天的学习。 工厂模式是设计模式 ......

一、引言

园子里有关设计模式的文章可以说数不胜数,之前也看过很多,但是其实理解都不深入,时间一长就忘了。最好是记录下来,总结中加深印象,这里也给刚开始进行开发的同学提个建议,不要因为自己写的不好而不去写,谁都是从菜鸟开始的,不断的总结才能将知识消化成自己的。

现在开始今天的学习。

工厂模式是设计模式中很重要的一个模式,其中有简单工厂模式(并不能算一个模式),工厂模式,抽象工厂模式。

工厂模式,从名字可以看出,这是一个创建型的模式,是用来创建对象。我们从简单工厂模式开始

二、简单工厂模式

简单工厂模式其实并不是一个设计模式,反而比较像一种变成习惯。为什么会出现简单工厂呢?

当使用"new"关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我们就不得不去修改此类的源码。

当我们需要实例化一个类时,不知道实例化哪个类,那么我们把这个变化封装起来,用一个工厂来帮我们创建对象。

这里我想用饭店的例子,先看类图:

设计模式第四篇-工厂模式

代码实现:

//食物接口
public interface food {
    //准备
    void prepare();
    //烹饪
    void cook ();
    //打包
    void box();
}

//具体食物 鱼
public class fish implements food {
    public void prepare() {
        system.out.println("洗鱼");
    }
    public void cook() {
        system.out.println("水煮鱼");
    }
    public void box() {
        system.out.println("大碗装鱼");
    }
}

//具体食物类 肉
public class meat implements food {
    public void prepare() {
        system.out.println("切肉");
    }
    public void cook() {
        system.out.println("红烧肉");
    }
    public void box() {
        system.out.println("装肉");
    }
}

运行

//简单工厂
public class simplefoodfactory {
    //静态创建工厂方法
    public static food createfood(string type){
        if(!type.isempty())
       {
           switch (type){
               case "fish":
                   return new fish();
               case "meat":
                   return new meat();
               default: return null;
           }
       }
       return null;
    }
}

 

运行结果:

设计模式第四篇-工厂模式

简单工厂模式很简单,也很容易理解。它带来了很多好处

1. 解决了客户端直接依赖于具体对象的问题,客户端可以消除直接创建对象的责任,而仅仅是消费产品。简单工厂模式实现了对责任的分割

2.代码复用,其他的客户也可以用这个工厂来创建对象。

但是缺点也很明显,扩展困难,一旦添加新菜单,工厂方法必须修改。工厂模式为我们解决这个问题。

三、工厂模式

先看一个结构图:

设计模式第四篇-工厂模式

从这个图中可以看出,工厂方法中创建对象不再是在一个类中,每一个具体的产品类都有一个创建工厂,其唯一的职责就是创建对应的产品,这是两个平行类层级

给出定义:定义了一个用于创建对象的接口,让子类来决定要实例化哪一个类,工厂方法让类把实例化延迟到其子类。

再改造下上面的例子

增加一个creator接口,并创建两个制造工厂fishcreator 和 meatcreator

//工厂基类,创建食物基类
public interface creator {
    food createfoddfactory();
}

//创建鱼工厂
public class fishcreator implements creator {
    public food createfoddfactory() {
        return new fish();
    }
}

//创建肉工厂
public class meatcreator implements creator {
    public food createfoddfactory() {
        return new meat();
    }
}

运行

private static void factory() {
//创建工厂
creator creator=new meatcreator();
//创建食物
food food = creator.createfoddfactory();
if(food!=null){
food.prepare();
food.cook();
food.box();
}
}

运行结果:

设计模式第四篇-工厂模式

工厂方法通过将实例化延迟到子类解决了逻辑判断问题,一旦需要扩展,只需要再添加一个子类及子类工厂即可,比如现在想要增加鸭子菜单,只需要增加一个鸭子类(duck)及一个鸭子工厂(duckcreator)即可。

下面介绍更抽象的抽象工厂模式

四、抽象工厂模式

工厂模式中一个工厂只创建一个产品,但是在现实的大厂中一般都是创建一系列产品,成为产品族,比如我们上面的例子,我们餐馆要开分店,然而每个地方的口味不一样,有些地方喜欢辣的,有些则喜欢不辣的,我们可以设计生产辣产品的工厂及不辣产品的工厂,那么这个时候就用到抽象工厂模式。

先看图:

设计模式第四篇-工厂模式

再结合之前的代码,我们进行修改,先创建一个抽象食物工厂,再创建辣和不辣的工厂

//抽象工厂
public interface foodfactory {
    //创建肉工厂
    meat createmeat();
    //创建鱼工厂
    fish createfish();
}

//制造辣的工厂
public class hotfoodfactory implements foodfactory {
    public meat createmeat() {
        return new hotmeat();
    }
    public fish createfish() {
         return new hotfish();
    }
}

//不辣的的工厂
public class nothotfoodfactory implements foodfactory {
    public meat createmeat() {
        return new nothotmeat();
    }
    public fish createfish() {
        return new nothotfish();
    }
}

再增加辣的肉和不辣的肉

//辣的肉
public class hotmeat extends meat {
    @override
    public void cook() {
        system.out.println("红烧辣的肉");
    }
}

//不辣的肉
public class nothotmeat extends meat {
    @override
    public void cook() {
        system.out.println("红烧不辣的肉");
    }
}

//辣的鱼
public class hotfish extends fish {
    @override
    public void cook() {
        system.out.println("做特别辣的鱼");
    }

}

//不辣的鱼
public class nothotfish extends fish {
    @override
    public void cook() {
        system.out.println("做不辣的鱼");
    }

}

运行

 private static void abstractfactory() {
        //辣工厂创建辣产品
        foodfactory hotfoodfactoryoodfactory=new hotfoodfactory();
        fish hotfish = hotfoodfactoryoodfactory.createfish();
        if(hotfish!=null){
            hotfish.prepare();
            hotfish.cook();
            hotfish.box();
        }
        system.out.println("-------------");
        meat hotmeat = hotfoodfactoryoodfactory.createmeat();
        if(hotmeat!=null){
            hotmeat.prepare();
            hotmeat.cook();
            hotmeat.box();
        }
    }

运行结果:

设计模式第四篇-工厂模式

抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展,这真是抽象工厂模式的优点所在,然后抽象模式同时也存在不足的地方。下面就具体看下抽象工厂的缺点(缺点其实在前面的介绍中以已经涉及了):

抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

知道了抽象工厂的优缺点之后,也就能很好地把握什么情况下考虑使用抽象工厂模式了,下面就具体看看使用抽象工厂模式的系统应该符合那几个前提:

  • 一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
  • 这个系统有多个系列产品,而系统中只消费其中某一系列产品
  • 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。

 一口学完了工厂模式,休息休息!