解析iOS应用开发中对设计模式中的抽象工厂模式的实现

概述
抽象工厂模式是对象的创建模式,它是工厂方法模式的进一步推广。

假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,可以引进抽象工厂模式。这样的话,消费产品的一方不需要直接参与产品的创建工作,而只需要向一个公用的工厂接口请求所需要的产品。

通过使用抽象工厂模式,可以处理具有相同(或者相似)等级结构中的多个产品族中的产品对象的创建问题。如下图所示:

根据产品角色的结构图,就不难给出工厂角色的结构设计图。
可以看出,每一个工厂角色都有两个工厂方法,分别负责创建分属不同产品等级结构的产品对象。

抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一个接口。一定要注意,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法。比如上面例子中的主板和CPU,都是为了组装一台电脑的相关对象。不同的装机方案,代表一种具体的电脑系列。

由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象就构成了一个产品族,也就是抽象工厂定义了一个产品族。

这就带来非常大的灵活性,切换产品族的时候,只要提供不同的抽象工厂实现就可以了,也就是说现在是以一个产品族作为一个整体被切换。

核心
先上一张图:

我们还是以苦逼的程序猿为例来说抽象工厂模式的一些核心概念。通过上图你可以发现,横纵二维坐标可以确定平面上一个唯一的点,这也就是抽象工厂的核心。

产品等级结构:就是继承结构。就像上面Android,IOS,PHP这些技能继承自一个抽象的技能类(譬如前面的ICode),这个抽象类与这些子类构成了产品等级结构。 同理的Android书,C语言书,脚本书继承自一个工具书类,这个工具书抽象类与这些子类构成了等级结构。

产品族:抽象工厂模式中的产品族官方定义是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。 譬如上面的Android位于技能等级结构中,Android书位于工具书等级结构中,Android技能和Android书是位于不同产品结构的一组产品,但是任何一个程序猿都需要具备技能和工具书, 譬如一个Android程序猿需要有Android技能及Android书,所以这个Android程序猿就是一个产品族。

概念: 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

重点: 抽象工厂模式结构重要核心模块:

抽象工厂:

声明一组用于创建一族产品的方法,每一个方法对应一种产品。

具体工厂:

实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

抽象产品:

它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。

具体产品:

定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

使用场景:

当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。 大白话意思就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类,像上面的技能与工具书), 并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。当然了, 同样的道理就是如果各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建。

程序实例
如下实例就是上图何如上文字解释的实现代码,具体不再解释:

代码如下:

package yanbober.github.io;
/*技能等级结构部分*/
interface ICode {
    void coding();
}

class CodeImplAndroid implements ICode {
    @Override
    public void coding() {
        System.out.println("Coding Android!");
    }
}

class CodeImplPHP implements ICode {
    @Override
    public void coding() {
        System.out.println("Coding PHP!");
    }
}
/*工具书等级结构*/
interface INeedBook {
    void lookBook();
}

class NeedBookImplAndroid implements INeedBook {
    @Override
    public void lookBook() {
        System.out.println("Look Android Book!");
    }
}

class NeedBookImplPHP implements INeedBook {
    @Override
    public void lookBook() {
        System.out.println("Look PHP Book!");
    }
}
/*产品族*/
interface IAbstractFactory {
    ICode getCodingSkill();
    INeedBook getNeedBook();
}

class FactoryImplAndroid implements IAbstractFactory {
    @Override
    public ICode getCodingSkill() {
        return new CodeImplAndroid();
    }

@Override
    public INeedBook getNeedBook() {
        return new NeedBookImplAndroid();
    }
}

class FactoryImplPHP implements IAbstractFactory {
    @Override
    public ICode getCodingSkill() {
        return new CodeImplPHP();
    }

@Override
    public INeedBook getNeedBook() {
        return new NeedBookImplPHP();
    }
}

public class Main {
    public static void main(String[] args) {
        IAbstractFactory factory = new FactoryImplAndroid();
        ICode code = factory.getCodingSkill();
        INeedBook book = factory.getNeedBook();
        code.coding();
        book.lookBook();

factory = new FactoryImplPHP();
        code = factory.getCodingSkill();
        book = factory.getNeedBook();
        code.coding();
        book.lookBook();
    }
}

技巧Tips:依旧可以使用配置与反射实现自动适应。

总结一把
抽象工厂模式的优点:

和前面一样,隔离具体类的生成,使客户并不需要知道什么被创建。
增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。
抽象工厂模式的缺点:

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,违背“开闭原则”。

(0)

相关推荐

  • 设计模式开发中的备忘录模式在iOS应用开发中的运用实例

    何为备忘录模式? 在响应某些事件时,应用程序需要保存自身的状态,比如当用户保存文档或程序退出时.例如,游戏退出之前,可能需要保存当前会话的状态,如游戏等级.敌人数量.可用武器的种类等.游戏再次打开时,玩家可以从离开的地方接着玩.很多时候,保存程序的状态真的不需要什么特别巧妙的方法.任何简单有效的方法都可以,但是同时,保存信息应该只对原始程序有意义.原始程序应该是能够解码它所保存文档中的信息的唯一实体.这就是备忘录模式应用于游戏.文字处理等程序的软件设计中的方式,这些程序需要保存当前上下文的复杂状

  • iOS App设计模式开发中对interpreter解释器模式的运用

    解释器模式 今天和大家分享的模式是解释器模式. 首先介绍一下解释器模式适合解决哪类问题. 其实,解释器模式需要解决的问题是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题. 就应用的例子来说,例如正则表达式就是它的一种具体应用,解释器可以为正则表示定义一个文法,如何表示一个特定的正则表达式,以及如何解释这个正则表达式. 解释器模式的类结构图如下. 图中的结构也比较好理解,解释器方法抽

  • 举例讲解设计模式中的原型模式在iOS应用开发中的作用

    1 前言 在许多面向对象的应用程序中,有些对象的创建代价过于大或者过于复杂.要是可以重建相同的对象并作轻微的改动,事情会容易许多.我们可以通过轻微的改动重用已有的对象,以适应程序中的特定情况.今天我们就来学习一下该模式. 2 详述 2.1 定义 应用于"复制"操作的模式成为原型(Prototype)模式.复制(cloning)指用同一模具生产一系列的产品.模具所基于的物品称为原型.尽管产品是用同一模具复制的,但是某些属性,如颜色与尺寸,可以稍有不同,但是他们还是属于同一类. 2.2 何

  • iOS App的设计模式开发中对State状态模式的运用

    1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得"力不从心了".随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,

  • 深入解析设计模式中的装饰器模式在iOS应用开发中的实现

    装饰器模式可以在不修改代码的情况下灵活的为一对象添加行为和职责.当你要修改一个被其它类包含的类的行为时,它可以代替子类化方法. 一.基本实现 下面我把类的结构图向大家展示如下: 让我们简单分析一下上面的结构图,Component是定义一个对象接口,可以给这些对象动态地添加职责.ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责.Decorator,装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需

  • 详解iOS App设计模式开发中对于享元模式的运用

    享元模式的概念 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pattern). 实现享元模式需要两个关键组件,通常是可共享的享元对象和保存他们的池.某种中央对象维护这个池,并从它返回适当的实例. 运用共享技术有效地支持大量细粒度的对象. 公共交通(如公共汽车)已有一百多年的历史了.大量去往相同方向的乘客可以分担保有和经营车辆(如公共汽车)的费用.公共汽车有

  • iOS App设计模式开发中对建造者模式的运用实例

    定义          "将一个复杂对象的构建与它的表现分离,使得同样的构建过程可以创建不同的表现". 看这个概念,可能感觉很是抽象,能看懂但是不知道有什么用.我们打一个比方来理解上面的定义.打比方之前,咱们先来聊聊这个设计模式是干什么用的?我们为什么要用这个模式呢?建造者模式负责将构建复杂对象的过程和它的部件解耦,也就是过程和部件的解耦.比如说汽车,是一个很复杂的对象,它有很多的部件,车轮.发动机.座椅.车门.油箱等等:它的组装过程也很复杂(需要专业人士按步骤进行装配),建造者模式就

  • iOS App设计模式开发中对迭代器模式的使用示例

    何为迭代器模式? 迭代器提供了一种顺序访问集合对象中元素的方法,而无需暴漏结构的底层表示和细节.遍历集合中元素的职能从集合本身转移到迭代器对象.迭代器定义了一个用于访问集合元素并记录当前元素的接口.不同的迭代器可以执行不同的策略. 例子 说了这么多,下面给大家展示一下类关系图. 上图中Client的右边是迭代器,左边是具体迭代的类型,在迭代器内部对具体需要迭代的类型进行了引用,还算不难理解吧,呵呵.其实,看起来是为了对具体类型进行解耦.好啦,下面给出具体的代码实现,简单的模拟了迭代器模式. 注意

  • 详解iOS应用开发中使用设计模式中的抽象工厂模式

    概述 我们知道简单工厂模式的优点是去除了客户端与具体产品的依赖,缺点是违反了"开放-关闭原则":工厂方法模式克服了简单工厂模式的缺点,将产品的创建工作放到具体的工厂类,每个工厂类负责生成一个产品.但是在实际应用中,一个工厂类只创建单个产品的情况很少,一般一个工厂类会负责创建一系列相关的产品,如果我们要设计这样的系统,工厂方法模式显然不能满足应用的需求,本章要介绍的抽象工厂模式,可以很好地解决一系列产品创建的问题. 定义 "提供一个创建一系列相关或相互依赖对象的接口,而无需指定

  • 实例解析设计模式中的外观模式在iOS App开发中的运用

    外观模式(Facade),为子系统中的一组接口提供一个一致的界面,此模式定义 一个高层接口,这个接口使得这一子系统更加容易使用. 下面给大家展示一下类的结构图,想必大家一看就明白了: 其实这个模式中,没有类与类之间的继承关系,只是进行了简单的类引用,统一了对外的接口而已.看起来是不是很简单?废话不多说了,下面简单向大家展示一下代码吧! 注意:本文所有代码均在ARC环境下编译通过. SubSystemOne类接口 复制代码 代码如下: #import <Foundation/Foundation.

随机推荐