2021年7月29日星期四

模板方法(学习笔记)

  1. 意图

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

  2. 动机

   假设正在开发一款分析公司文档的数据挖掘程序。用户需要向程序输入各种格式(PDF、DOC或CSV)的文档,程序则会从这些文档中抽取出有意义的数据,并以统一的格式将其返回给用户。一段时间后,你发现这三个类包含了许多相似的代码。尽管这些类处理不同数据格式的代码完全不同,但是数据处理和分析的代码却完全一样。怎样能在保持算法结构完整的情况下去除重复代码呢?另外,还有一个与使用这些类的客户端代码相关的问题:客户端代码中包含许多条件语句,以根据不同的处理对象类型选择合适的处理过程。如果所有处理数据的类都拥有相同的接口或基类, 那么你就可以去除客户端代码中的条件语句, 转而使用多态机制来在处理对象上调用函数

 

  模板方法模式建议将算法分解为一系列步骤,然后将这些步骤改写为方法,最后在 "模板方法" 中依次调用这些方法。步骤可以是抽象的,也可以有一些默认的实现。为了能够使用算法,客户端需要自行提供子类并实现所有的抽象步骤。如有必要还需重写一些步骤(但这一步中不包括模板方法自身)。有两种类型的步骤:

  • 抽象步骤必须由各个子类来实现
  • 可选步骤已有一些默认实现, 但仍可在需要时进行重写

  还有另一种名为钩子的步骤。钩子是内容为空的可选步骤。即使不重写钩子,模板方法也能工作。钩子通常放置在算法重要步骤的前后,为子类提供额外的算法扩展点 

  3. 适用性

  • 一次性的实现一个算法的不变部分,并将可变的行为留给子类来实现
  • 各子类中公共的行为应该被提取出来并集中到一个公共父类中以避免代码重复。
  • 控制子类扩展。模板方法只在特定点调用钩子操作,这样只允许在这些点进行扩展

  4. 结构

   

  5. 效果

  模板方法是一种代码复用的基本技术。它们在类库中尤为重要,提取了类库中的公共行为。模板方法导致了一种反向的控制结构,这种结构有时被称为好莱坞法则,即一个父类调用一个子类的操作,而不是相反

  模板方法调用下列类型的操作:

  1. 具体操作(ConcreteClass或对客户类的操作)

  2. 具体的AbstractClass的操作

  3. 原语操作(AbstractClass中定义抽象的原语操作,具体的子类将重定义它们以实现一个算法的各步骤)

  4. 工厂方法

  5. 钩子操作,它提供了缺省行为,子类可以在必要时进行扩展。钩子操作在通常情况下是空操作  

  6. 代码实现  

  本例中,模版方法模式定义了一个可与社交网络协作的算法。与特定社交网络相匹配的子类将根据社交网络所提供的API来实现这些步骤

  networks/Network.java: 基础社交网络类

package template_method.networks;/** * @author GaoMing * @date 2021/7/25 - 21:47 * Base class of social network. */public abstract class Network { String userName; String password; Network() {} /**  * Publish the data to whatever network.  */ public boolean post(String message) {  // Authenticate before posting. Every network uses a different  // authentication method.  if (logIn(this.userName, this.password)) {   // Send the post data.   boolean result = sendData(message.getBytes());   logOut();   return result;  }  return false; } abstract boolean logIn(String userName, String password); abstract boolean sendData(byte[] data); abstract void logOut();}

  networks/Facebook.java: 具体社交网络

package template_method.networks;/** * @author GaoMing * @date 2021/7/25 - 21:47 */public class Facebook extends Network { public Facebook(String userName, String password) {  this.userName = userName;  this.password = password; } public boolean logIn(String userName, String password) {  System.out.println("\nChecking user's parameters");  System.out.println("Name: " + this.userName);  System.out.print("Password: ");  for (int i = 0; i < this.password.length(); i++) {   System.out.print("*");  }  simulateNetworkLatency();  System.out.println("\n\nLogIn success on Facebook");  return true; } public boolean sendData(byte[] data) {  boolean messagePosted = true;  if (messagePosted) {   System.out.println("Message: '" + new String(data) + "' was posted on Facebook");   return true;  } else {   return false;  } } public void logOut() {  System.out.println("User: '" + userName + "' was logged out from Facebook"); } private void simulateNetworkLatency() {  try {   int i = 0;   System.out.println();   while (i < 10) {    System.out.print(".");    Thread.sleep(500);    i++;   }  } catch (InterruptedException ex) {   ex.printStackTrace();  } }}

  networks/Twitter.java: 另一个社交网络

package template_method.networks;/** * @author GaoMing * @date 2021/7/25 - 21:47 */public class Twitter extends Network{ public Twitter(String userName, String password) {  this.userName = userName;  this.password = password; } public boolean logIn(String userName, String password) {  System.out.println("\nChecking user's parameters");  System.out.println("Name: " + this.userName);  System.out.print("Password: ");  for (int i = 0; i < this.password.length(); i++) {   System.out.print("*");  }  simulateNetworkLatency();  System.out.println("\n\nLogIn success on Twitter");  return true; } public boolean sendData(byte[] data) {  boolean messagePosted = true;  if (messagePosted) {   System.out.println("Message: '" + new String(data) + "' was posted on Twitter");   return true;  } else {   return false;  } } public void logOut() {  System.out.println("User: '" + userName + "' was logged out from Twitter"); } private void simulateNetworkLatency() {  try {   int i = 0;   System.out.println();   while (i < 10) {    System.out.print(".");    Thread.sleep(500);    i++;   }  } catch (InterruptedException ex) {   ex.printStackTrace();  } }}

  Demo.java: 客户端代码

package template_method;import template_method.networks.Network;import template_method.networks.Twitter;import template_method.networks.Facebook;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;/** * @author GaoMing * @date 2021/7/25 - 21:47 */public class Demo { public static void main(String[] args) throws IOException {  BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))......

原文转载:http://www.shaoqun.com/a/892282.html

跨境电商:https://www.ikjzd.com/

首信易支付:https://www.ikjzd.com/w/1841

gtin:https://www.ikjzd.com/w/136

雨果:https://www.ikjzd.com/w/1307


1.意图  定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤  2.动机  假设正在开发一款分析公司文档的数据挖掘程序。用户需要向程序输入各种格式(PDF、DOC或CSV)的文档,程序则会从这些文档中抽取出有意义的数据,并以统一的格式将其返回给用户。一段时间后,你发现这三个类包含了许多相似的代码。尽管这
四川温泉有哪些?四川温泉旅游线路推荐:http://www.30bags.com/a/429675.html
四川温泉有哪些?四川温泉旅游线路推荐_峨眉山旅游攻略_峨眉山旅游景点:http://www.30bags.com/a/415422.html
四川汶川多地泥石流灾害 2人失联3人被困:http://www.30bags.com/a/424909.html
四川卧龙暴雨引发泥石流 12400名旅客被疏散:http://www.30bags.com/a/424927.html
在教室深深挺进同桌花蕊里 脱下漂亮班花校裙按着臀强行干:http://lady.shaoqun.com/a/246826.html
极品的一家人让我很讨厌:http://lady.shaoqun.com/a/123610.html
快点拔出来老师快受不了了 老师你下面好紧好湿好爽:http://lady.shaoqun.com/m/a/248419.html
描写的很细致的h文看湿 他掰开了我双腿进去了:http://lady.shaoqun.com/m/a/247723.html
深圳宝安科技馆8月展览汇总(持续更新):http://www.30bags.com/a/517601.html
2021时尚深圳展蝶讯馆展览好看吗:http://www.30bags.com/a/517602.html
2021时尚深圳蝶讯馆观展攻略:http://www.30bags.com/a/517603.html
深圳欢乐谷夏浪音乐节有朱星杰吗:http://www.30bags.com/a/517604.html

没有评论:

发表评论