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

一、引言

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

现在开始今天的学习。

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

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

二、简单工厂模式

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

当使用"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();
        }
    }

运行结果:

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

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

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

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

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

 

原文地址:https://www.cnblogs.com/yuanqinnan/p/10161785.html

时间: 2024-08-06 14:56:15

设计模式第四篇-工厂模式的相关文章

C#设计模式系列:简单工厂模式(Simple Factory)

1.简单工厂模式简介 1.1>.定义 简单工厂模式定义一个Factory类,可以根据参数的不同返回不同类的实例,被创建的实例通常有共同的父类. 简单工厂模式只需要一个Factory类. 简单工厂模式又称为静态工厂模式,Factory类为静态类或包含静态方法. 1.2>.使用频率  中 2.简单工厂模式结构 2.1>.结构图 2.2>.参与者 简单工厂模式参与者: ◊ Product:抽象产品类,将具体产品类公共的代码进行抽象和提取后封装在一个抽象产品类中. ◊ ConcretePr

设计模式学习03—抽象工厂模式

1.动机与定义 工厂模式中,一个工厂仅仅能提供一个或一类产品,当产品种类较多,形成产品系列(比方我们要创建跨平台的button,菜单,文本框等等一系列GUI控件: 单纯使用工厂模式会产生大量工厂,并且后期维护也不方便,我们能够从产品中找到规律,假设产品等级相对固定,以后仅仅会新增产品族,那么我们就能够把整个产品族放到一个工厂创建,以后新增其它系统产品族也很方便,例如以下图: 这样的模式就是抽象工厂,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则须要面对多个产品等级结构,一个工厂等级结构能

(设计模式之一)浅析简单工厂模式

简单工厂模式 举个两个例子: 我输入两个数字和(+ - * /)其中一个符号,计算出两个数的结果. 饲养员让(狗 猫 鸟 猪)其中一个动物 叫 这里就是一个简单的工厂模式, 用户只需要提供他需要的接口,而不需要知道具体的实现 工厂判断用户提供的接口,创建对应的子类对象, 返回父类变量给用户(这里涉及里氏替换原则:声明父类变量替换子类对象) 当后面追加新的操作类例如:求根类  求平方类 , 从数据安全角度: 只需要创建新的类继承于Operation抽象类 ,从而不影响其他操作类(+ - * /),

常见的设计模式:单例模式、工厂模式、观察者模式、装饰模式与适配器模式

常见的设计模式:单例模式.工厂模式.观察者模式.装饰模式与适配器模式 这里可以阅读Terry Lee的设计模式系列来理解学习一下 1.4.1 单例模式 .NET设计模式(2):单件模式(Singleton Pattern)  http://terrylee.cnblogs.com/archive/2005/12/09/293509.html 1.4.2 抽象工厂模式 .NET设计模式(3):抽象工厂模式(Abstract Factory) http://terrylee.cnblogs.com/

初探设计模式(1)——工厂模式

从今天起,打算系统学习一下设计模式,先从工厂模式开始,本系列的文章只是对设计模式初步学习的总结,如有写的不对的地方欢迎指正. 什么是工厂模式呢?所谓工厂在我们的日常生活中就是生产产品的地方,如汽车工厂,玩具工厂等,在程序的世界中,设计到"生产产品"字眼的是什么?没错,就是创建对象! "工厂"通俗来说就是一个创建对象(产品)的地方.工厂模式(Factory Pattern)是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式,是 Java 中最常用的设

设计模式C++实现——抽象工厂模式

模式定义: 抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类. 抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道实际产出的具体产品时什么.这样一来,客户就从具体的产品中被解耦了. 模式结构: 举例: 数据库访问程序设计,不同的数据库访问方式可能不一样,为了抽象对对不同数据库的访问,可以将数据库隐藏起来,提供统一的访问方式,用多态进行实现. UML设计: 编程实现及执行结果: #include <iostream> using namespace st

设计模式学习(二)-简单工厂模式

---恢复内容开始--- 简单工厂设计模式 简单工厂模式定义: 简单工厂设计模式又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式.在简单工厂模式中,可以根据参数的不同返回不同类的实例.简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 简单工厂主要分为如下几个角色 抽象产品(abstract product):为所有具体产品的抽象表现,一般为抽象类 具体产品(product):为抽象产品的具体实现 生成产品工厂(facto

[设计模式篇]工厂模式和抽象工厂模式

最近在看Head First的Design Pattern,想想去年候捷来学校给我们讲Design Pattern,但当时水平太弱根本听不懂,今年想趁机再好好学一波,候捷反而不来了,哎,人生就是这样,有些机会真的搞不好只有一次了,所以还是要多多珍惜,不然... ... (再水下去估计没人看了,废话少说,这篇就当一个开篇之作吧,虽然已经看了不少了.) Head First这本书用了一个披萨店的例子,从简单工厂(严格来说这不算一种Gof的设计模式,更像是一种编程习惯),到介绍工厂模式,再介绍到抽象工

设计模式四之工厂模式1

从学习设计模式以来,一直强调接口编程,依赖抽象而不是具体,但是每次看到new出新的对象,是不是就会有些疑问呢?怎么会这样,难道只能这样吗?似乎java中只提供了这种从类中生成对象的方式,不用怀疑,java确实只有这种基础的生成对象的方式,但是我们可以抽象它,使我们的调用代码在更高级的层面上来生成对象,根据不同的业务需求来获取对象. 工厂模式有三种,一种是简单工厂,再有一种是工厂方法,最后一种是抽象工厂. 简单工厂一般都写成静态工厂,如下, package com.csshu.simple; /*