Android设计模式之“组件协作模式”: 模板方法Template Method
HunBeane
8年前
<h2><strong>GOF-23 模式分类</strong></h2> <p><strong>“目的”角度</strong></p> <ul> <li> <p>创建型(Creational)模式<br> 将 <strong>对象的部分创建工作延迟到子类或其他对象</strong> ,从而应对需求变化给 <strong>对象创建时具体类型实现</strong> 引来的冲击</p> </li> <li> <p>结构型(Structural)模式<br> 通过 <strong> 类继承 </strong> 或者 <strong> 对象组合获 </strong> 得更灵活的结构,从而应对需求变化给 <strong> 对象的结构 </strong> 带来的冲击</p> </li> <li> <p>行为型(Behavioral)模式<br> 通过 <strong> 类继承 </strong> 或 <strong> 对象组合 </strong> 来划分类与对象间的职责,从而应对需求变化给 <strong> 多个交互的对象 </strong> 带来的冲击</p> </li> </ul> <p><strong>“范围”角度</strong></p> <ul> <li> <p><strong>类模式 </strong> 处理 类与子类 的 静态关系 (类关系是静态的,写好的代码结构决定)</p> </li> <li> <p><strong>对象模式 </strong> 处理 对象 间的 动态关系 (对象关系是动态的,运行时具体情况而定)</p> </li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/35656e0ac6f63dd0834e8536d2fe36a6.png"></p> <p>从“封装变化”角度进行模式分类</p> <p>找稳定点和变化点的角度去理解运用设计模式</p> <p><img src="https://simg.open-open.com/show/210f5c5ed02e7cc3f05d86a5f95ace1a.png"></p> <h2><strong>重构获得模式 Refactoring to Patterns</strong></h2> <ol> <li> <p>面向对象设计模式是“好的面向对象设计”,所谓“好的面向对象设计”指的是可以满足“ <strong>应对变化,提高复用</strong> ”的设计</p> </li> <li> <p>现代软件设计的特征是“需求频繁变化”。设计模式的要点是“ <strong>寻找变化点</strong> ,然后 <strong>在变化点处应用设计模式</strong> ,从而提高对需求变化的应对能力”。“ <strong>什么时候、什么地点应用</strong> 设计模式”比“理解设计模式结构本身”更为重要。</p> </li> <li> <p>设计模式的应用 <strong>不宜先入为主</strong> ,一上来就使用设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷软件开发实践提倡的“Refactoring to Patterns”是目前普遍公认的最好的使用设计模式的方法。</p> </li> </ol> <p><strong>推荐书籍 -- 重构</strong></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/7459576cee38402e062b7340638983dd.png"></p> <p style="text-align:center">重构中找到设计模式的最佳用法</p> <h3><strong>重构的关键技法</strong></h3> <ol> <li> <p>静态 ---> 动态</p> </li> <li> <p>早绑定 ---> 晚绑定</p> </li> <li> <p>继承 ---> 组合</p> </li> <li> <p>编译时依赖 ---> 运行时依赖</p> </li> <li> <p>紧耦合 ---> 松耦合</p> </li> </ol> <h3><strong>一、 “组件协作”模式</strong></h3> <ul> <li>大型软件开发一般将“框架 --- 应用程序”划分开来。“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的 <strong>松耦合</strong> ,是二者之间协作时常用的模式。</li> <li>典型模式 <ol> <li>Template Method (模板方法 模式)</li> <li>Strategy (策略 模式)</li> <li>Observer / Event (观察者/事件 模式)</li> </ol> </li> </ul> <p>本篇笔记就讲述“Template Method (模板方法 模式)”</p> <p><strong>Template Method 模板方法 模式</strong></p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/856a8889d1957374ebca79ebfa077bc1.png"></p> <p><strong>模式定义</strong></p> <p>定义某一操作的 <strong>算法骨架(稳定的)</strong> ,将一些不能立刻确定的 <strong>步骤(变化的)</strong> 延迟到子类中(定义为抽象方法,子类实现)。Template Method使得子类可以 <strong>不改变(复用)</strong> 一个 算法 的结构,即可 <strong>重定义(override 重写)</strong> 该算法的某些特定步骤。</p> <p><strong>组成:</strong></p> <ol> <li>父类 + 算法(流程) + 抽象函数</li> <li>子类 + 实现抽象函数 + 调用父类算法</li> </ol> <p><strong>模式结构(Structure)</strong></p> <p>类图表示</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/856a8889d1957374ebca79ebfa077bc1.png"></p> <p><strong>动机 Motivation(针对的问题是什么)</strong></p> <ul> <li> <p>问题:软件构建过程,对某一任务,有稳定不变的整体操作结构、流程,但有个别子步骤会根据需求改动,又或者其他固有原因(如框架和应用间的关系)无法和任务整体结构同时实现(类似于点击事件的实现)</p> </li> <li> <p>要得到的结果:在确定稳定操作结构的前提下,灵活应对各个子步骤的变化或者晚期实现需求。</p> </li> </ul> <p>要怎么实现上述诉求呢?</p> <p>把稳定的结构抽取出来,放到Library(框架)里面,把不稳定的子步骤(方法的实现)配置为抽象的(当应用程序使用到该库的时候需要实现的),留给应用开发者去实现。</p> <p>类似于Android中的点击函数,如何获取点击事件并响应,这个操作流程肯定是稳定的,不需要我们操心,但是具体如何响应则是不稳定的,不同app的按钮对应的意义操作不一,辣么就把响应方法设置为抽象的,让我们去重写实现即可。框架就可以在稳定的按钮点击事件流程中,适应不同的需求。</p> <p>这就是把原有的结构化的程序设计,通过面向对象的程序设计进行改造,以得到更好的应对变化的特性。</p> <p>程序开发人员也可以减少代码量,因为稳定的结构已经被封装在库里面,我们只需要完成这个结构中不稳地的部分(实现其抽象方法)。</p> <p><img src="https://simg.open-open.com/show/3f719494784475afea51fec880aceaf6.png"></p> <p style="text-align:center">结构化设计流程</p> <p><img src="https://simg.open-open.com/show/a58cf11b3993fd54a734ea4a19b4e889.png"></p> <p style="text-align:center">面向对象软件设计流程</p> <p><img src="https://simg.open-open.com/show/65add02570b963bf561b92bd25c4653f.png"></p> <p style="text-align:center">早绑定与晚绑定</p> <p><strong>早绑定:</strong>晚的类调用早的类(把早的类绑定到晚的类当中)</p> <p><strong>晚绑定:</strong>早的类调用晚的类(把晚的类绑定到早的类当中)</p> <p><strong>实现机制: 虚函数的多态调用</strong> 。因为函数是抽象的,会在晚的类中被实现(因为子类必须要实现父类的抽象方法),早的类中就会调用晚的类中的实现。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/192090fd009f297edba3eedd65a3c327.png"></p> <p style="text-align:center">虚函数的多态调用</p> <p>总结要点</p> <ol> <li> <p>Template Method模式是常见的基础性的设计模式,一般的面向对象程序都会大量的应用它。使用最简洁的机制(虚函数多态性)为很多应用程序框架提供了灵活的 <strong>扩展点</strong> ,是代码复用方面的基本实现结构。</p> </li> <li> <p>反向控制结构是Template Method的典型应用:“你别调用我,帮我实现那个方法就好,我来调用你,因为对整个流程你懂个屁”</p> </li> <li> <p>在具体实现(运用)时,被Template Method调用的虚方法可以距有实现的,也可以是没有任何实现(抽象方法、纯虚方法),但一般推荐设置为 <strong>protected</strong> 方法(只有子类可以调用、重写)。</p> </li> </ol> <p> </p> <p>来自:http://www.jianshu.com/p/f10a5b8f1f5d</p> <p> </p>