X-gen设计模式综合实战5-具体调用模块

1.详细功能

  • 能够控制整个X-gen的调用过程,并能够灵活地扩展这个调用过程
  • 调用theme提供的Action来具体实现每一个需要生成的功能
  • 能够在每个Action执行前后,动态组合添加一些功能
  • 能很灵活地通知多个输出实现,并能实现调用模块和输出模块的解耦

2.功能边界

  • 只负责具体的generate调用过程
  • 不关心generate的数据从何而来
  • 不关心实际如何generate
  • 不关心按照什么流程顺序来generate
  • 不关心每个步骤都需要完成些什么功能,那都不是固定的,完全可以通过配置或者是开发人员在外部theme中来定

3.对外的接口

4.内部实现

实现的起点
为了让大家更好的理解调用模块的内部实现架构,因此先以一个最简单的实现结构为起点,采用重构的方式,逐步把相关的设计模式应用进来,从简单到复杂,从而让大家更好的看到如何选择要使用的设计模式、如何实际应用设计模式以及如何让多种设计模式协同工作。

1.针对前面定义的API,提供一个最基本的实现。其实,真正调用的实现就相当于命令模式的receiver

4.1 状态模式

4.1.1 面临的问题

来思考上面的实现,现在在executeGen方法里面只有两步实现,可是不排除今后有更多需要调用的功能,比如:在内容生成后执行事件处理等等。

通常情况下,我们还希望保持DefaultGenInvocation的通用性,该怎么办呢?换句话说,executeGen方法里面的调用流程是可能变动的,或者是需要添加新的流程步骤,或者是需要改变调用的顺序等等。

该怎么实现这样的功能呢?

4.1.2 用状态模式来解决

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。


4.1.3 使用状态模式来解决问题的思路

要解决上面的问题,一个很简单的思路就是:其实就是相当于用状态模式来模拟调用的工作流程,把调用流程的每一步单独包装成为一个状态对象,然后在一个对象执行过后,由这个状态对象来设置下一步状态,使得流程继续流转。

4.1.4 此时具体调用模块的结构示意如图

4.2 模板方法

4.2.1 面临的问题

面临的问题在调用每个theme的action来generate内容的时候,虽然action是由theme提供的,也就是由开发人员自行扩展的,但是调用action的过程是一样的。

有些朋友会想,调用过程一样的,那就做成公共的功能吧,但是又发现其中某些步骤执行的功能并不一样,比如具体的action的处理是不一样的,这该如何处理呢?

4.2.2 用模板方法模式来解决

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。


4.2.3 使用模板方法模式来解决问题的思路

既要约束子类的功能,又要为子类提供公共的功能,很明显应用抽象类来做一个公共的父类。而公共功能中某些步骤执行的功能并不一样,那就可以把这些不一样的功能延迟到子类来执行,在父类中只要定义相应的抽象方法就好了。

从而把调用过程看成是算法的骨架,而调用action的处理方法,当作原语操作,只有子类才知道如何实现具体的generate;而在action操作前后调用的方法,并不是每个generate都需要的功能,因此可以当作钩子方法来实现,也就是在父类中给出默认的实现,而子类根据需要来覆盖。

4.2.4 此时具体调用模块的结构示意如图

4.3 工厂方法

4.3.1 面临的问题

面临的问题观察上面的实现,发现在模板方法generate里面,调用的第一步,需要得到用来封装generate内容的对象。

但是在父类里面,它并不知道究竟要generate成为什么样子,只有theme中的action才知道具体是什么类型,也就是说父类不知道某个对象的类型,也不知道如何获取这个对象,该怎么办呢?

4.3.2 用工厂方法模式来解决

定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到其子类。


4.3.3 使用工厂方法模式来解决问题的思路

要解决上面的问题,一个很简单的思路就是:在父类里面定义一个抽象方
法,返回模板方法需要的对象,把初始化对象的任务延迟到子类去。

这个方法就是一个工厂方法,同时也作为模板方法模式里的原语操作之一。

4.3.4 此时具体调用模块的结构示意如图

4.4 装饰器

4.4.1 面临的问题

面临的问题分析上面的实现,在调用模板方法generate的过程中,可能需要在具体的 Action之前执行一定的功能,也可能需要在具体的Action之后执行一定的功能,而且这些功能具体是什么,具体的Action方法并不知道。

也就是说,需要在Action方法不知情的情况下,给他添加上新的功能,可能会在action方法之前或者之后执行一些功能。该怎么办呢?

4.4.2 用装饰者模式来解决

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式比生成子类更为灵活。


4.4.3 使用装饰者模式来解决问题的思路

要解决上面的问题,一个很简单的思路就是:定义一个公共的组件对象,作为原始对象和装饰对象的父类,然后在装饰对象里面,采用动态组合的方式来给传入的组件对象透明的添加新的功能

4.4.4 此时具体调用模块的结构示意如图

4.5 观察者模式

4.5.1 面临的问题

继续分析上面的实现,在加入了模板方法模式、工厂方法模式和装饰器模式过后,在DefaultGenInvocation的executeGen方法里面,调用每个theme的 action来生成内容的功能就很容易实现出来了。

可是,把内容输出去的步骤应该怎么实现呢?

按照现在的要求,同一个generate的功能,可能会有多个输出,输出形式还不一样,那么,该怎么实现这个功能呢?

4.5.2 用观察者模式来解决

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。


4.5.3 使用观察者模式来解决问题的思路

要解决上面的问题,一个很简单的思路就是:把生成调用当成目标对象,而需要输出的对象当成多个观察者,这样一来,当目标对象的状态变化的时候,也就是需要输出的内容已经generate过后,就可以通知这多个观察者,让这些观察者自行输出内容。

4.5.4 此时具体调用模块的结构示意如图

5.和其他模块的交互实现

使用中介者模式

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,193评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,306评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,130评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,110评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,118评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,085评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,007评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,844评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,283评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,508评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,395评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,985评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,630评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,797评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,653评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,553评论 2 352

推荐阅读更多精彩内容

  • 设计模式概述 在学习面向对象七大设计原则时需要注意以下几点:a) 高内聚、低耦合和单一职能的“冲突”实际上,这两者...
    彦帧阅读 3,741评论 0 14
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,622评论 18 399
  • 今天是2017.03.11号,历时2个多月的无人机项目暂时告一段落了. 说下暂时没能实现的吧,悟2 相机视角不能调...
    六朝阅读 776评论 2 2
  • 今早起来意识到昨晚没有在简书写字。 大概是因为这两天一直在做文字性工作的原因。给各类领导写稿子,实在不会写务虚的东...
    lichangan阅读 261评论 0 0