文章目录

  • 模版方法模式
  • 1、模式说明
  • 2、结构图
  • 3、案例代码
  • 3.1、抽象父类
  • 3.2、子类实现1
  • 3.3、子类实现2
  • 3.4、客户端调用
  • 策略模式
  • 1、模式说明
  • 2、基本的策略模式结构图
  • 3、模版方法+策略模式+简单工厂案例代码
  • 3.1、Context类
  • 3.2、客户端调用


模版方法模式

1、模式说明

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

【适用场景】:当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模饭方法模式来处理。

【优势】:模板方法模式是通过把不变行为拥移到超类,去除子类中的重复代码来体现它的优势。当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

2、结构图

设计模式之模版方法模式与策略模式_父类

AbstractClass是抽象类,其实也就是一抽象模板,定义并实现了一个模版方法:TemplateMethod()。这个模版方法一般是一个具体方法,供外部调用。它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个个AbstractClass都可以有任意多个
ConcreteClass与之对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

3、案例代码

3.1、抽象父类

public abstract class AbstractParentClass {
    /**
     * 抽象方法一(由子类实现)
     */
  	protected abstract void abstractOpration1();
    /**
     * 抽象方法二(由子类实现)
     */  
  	protected abstract void abstractOpration2();
		
    /**
     * 模版方法,组织整个算法逻辑,供外部调用
     */  
  	public void TemplateMethod(){
      	// 得到每个子类实现返回的数据
      	abstractOpration1();
      	abstractOpration2();
      	
      	// 对数据进行处理
      	assembleResponse(); 
    }
  
  	private void assembleResponse(){
      	// 数据处理逻辑 
    }

}

3.2、子类实现1

public class ChildrenOne extends AbstractParentClass {
     
    /**
     * 子类实现 方法一
     */   
  	protected abstract void abstractOpration1() {
      	// 执行ChildrenOne此类自己的数据处理逻辑,查a表,返回结果
    }

  
    /**
     * 子类实现 方法二
     */   
  	protected abstract void abstractOpration2() {
      	// 处理逻辑
    }
}

3.3、子类实现2

public class ChildrenTwo extends AbstractParentClass {
    /**
     * 子类实现 方法一
     */   
  	protected abstract void abstractOpration1() {
      	// 执行ChildrenTwo此类自己的数据处理逻辑,查a表,返回结果
    }

  
    /**
     * 子类实现 方法二
     */   
  	protected abstract void abstractOpration2() {
      	// 处理逻辑
    }
}

3.4、客户端调用

public class test {
    public static void main(String[] args) {
      	// 父类的引用指向子类的实现(多态)
      	AbstractParentClass parent1 = new ChildrenOne();
      	parent1.TemplateMethod();
            	
      
      	AbstractParentClass parent2 = new ChildrenTwo();
      	parent2.TemplateMethod();
    }
}

策略模式

1、模式说明

【策略模式】:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。

【适用场景】:策略模式封装了变化。策略模式就是用来封装算法的,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

【优点】:

  • 降低耦合:策略模式是一种定义一系列算法法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以相同的的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。
  • 策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。
  • 简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。每个算法可保证它没有错误,修改其中任一个时也不会影响其他的算法。
  • 在基本的策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。这本身并没有解除客户端需要选择判断的压力,而策略模式与简单工厂模式结合后,选择具体实现的职责也可以由Context来承担,这就最大化地也减轻了客户端的职责

2、基本的策略模式结构图

设计模式之模版方法模式与策略模式_设计模式_02

Strategy类,定义所有支持的算法的公共接口。它是一个抽象父类。提供的公共接口是一个抽象方法,由其子类去实现具体的逻辑。

Context类,维护了Strategy类的一个引用。不过这个类也可以用来做简单工厂模式里的工厂类,用来选择具体的算法。

3、模版方法+策略模式+简单工厂案例代码

模版方法的代码还是采用上面的。然后你会发现抽象父类AbstractParentClass与它的实现子类ChildrenOne、ChildrenTwo正对应着策略模式中的Strategy类与其子类。所以我们只需要增加一个Context类,并在Context类中做一些工厂类所做的事情。

3.1、Context类

public class StrategyContext {
  	// 此方法也可返回List<AbstractParentClass>,具体使用可变通
  	public static AbstractParentClass getStrategy(String type) {
			switch (type) {
        case "one":
          return new ChildrenOne();
          break;
        case "two":
          retrun new ChildrenTwo();
          break;
        default:
          return null;
          break;
      }
    }
  
}

如果策略父类只曝漏了一个模版方法,Context类也可这样写:

public class StrategyContext {
  	
  	AbstractParentClass parent = null;
  
  	// 一个构造方法
  	public StrategyContext(String type) {
			switch (type) {
        case "one":
          parent = new ChildrenOne();
          break;
        case "two":
          parent = new ChildrenTwo();
          break;
        default:
          parent = null;
          break;
      }
    }
  
  public void executeTemplateMethod() {
    parent.TemplateMethod();
  }
  
}

这样整体对外曝漏的只有StrategyContext这个类,之后新增策略,改代码的成本低些。

3.2、客户端调用

public class test {
    public static void main(String[] args) {
      	// 父类的引用指向子类的实现(多态)
      	AbstractParentClass parent1 = StrategyContext.getStrategy("one");
      	parent1.TemplateMethod();
    }
}