漫谈设计模式笔记:模板模式

场景:  为了回家过年,我们都要先买火车票,然后坐火车,最后才能和家人团聚。

程序:

这里我们写个简单程序模拟回家过年。新建了一个NewYear类,它有一个celebrateSpringFestival()的方法,我们把买票,坐车,回家庆祝都写在这个方法。

  

public class NewYear {
      public void celebrateSpringFestival(){
    	  //1.买票
    	  System.out.println("买票");
    	  
    	  //2.乘火车
    	  System.out.println("乘火车");
    	  
    	  //3.庆祝新年
    	  System.out.println("新年快乐!");
      }
   }

 

我们回家坐车,可以选择火车,汽车,飞机,因人而异。但不管坐哪种交通,都要先买票,再坐车,最后才回家过年。于是我们又新建一个类PassengerByCoach,由于买票和在家庆祝是一样的,只需要改乘坐交通方式的代码改而已。

      代码如下:

        

public class PassengerByCoach{
	public void celebrateSpringFestival(){
  	  //1.买票
  	  System.out.println("买票");
  	  
  	  //2.乘汽车
  	  System.out.println("乘汽车");
  	  
  	  //3.庆祝新年
  	  System.out.println("新年快乐!");
    }
}

 

如果我们要坐飞机,也是同样的代码,只改乘坐的交通方式的代码。随着交通工具的增多,以后要开发更多的类和测试类。这样,维护起来就麻烦了。为了解决重复代码出现,出现了模板模式的方法。

     为了重复使用代码,我们使用继承机制。因为买票和在家庆祝两个功能是一样,所以抽出一个父类,把这些相同逻辑写在父类,因此有了buyTicket()celebrate()两个方法。而乘坐交通方式写成travel()方法,让子类去实现各自不同的乘坐方式。并且在父类定义一个celebrateSpring()方法供客户端调用,实现买票,坐车,庆祝三个顺序的招待。

   

父类:

public abstract class HappyNewYear {

//1.买票,final不让子类个性其方法

    protected final void buyTicket(){

     System.out.println("买票");

    };

    

    //2.子类要实现的具体乘坐方式

    protected abstract void travel();

    

    

    //3.庆祝

    protected final void celebrate(){

     System.out.println("新年快乐!");

    };

    

    

    public void celebrateSpring(){

     buyTicket();

     travel();

     celebrate();

    }

}

 

现在编写子类,实现一个乘坐飞机的子类。

  

	public class PassengerbyAir extends HappyNewYear {
	     
		
		@Override
		protected void travel() {
			System.out.println("坐飞机");
	
		}

	}

同样,可以再写乘坐汽车,乘坐火车的两个子类。

 

	 public class PassengerbyCoach extends HappyNewYear {
		@Override
		protected void travel() {
			System.out.println("坐汽车");
	
		}
	
	}
	
	   public class PassengerbyTrain extends HappyNewYear {
	     
		
		@Override
		protected void travel() {
			System.out.println("坐火车");
	
		}
	
	}
	

结果:

     ...CiCi准备回家...

买票

坐飞机

新年快乐!

 

...GiGi准备回家

买票

坐汽车

新年快乐!

 

...MiMI准备回家

买票

坐火车

新年快乐!

 

 

总结:

使用继承,子类中不需要实现那些重复买票和庆祝过年的代码,只需要实现不同的回家方式代码,避免了代码的重复。父类中的celebrate()方法是一个模板方法(也叫框架方法),它把回家过年分为三步,其中方法travle是抽象方法,用于子类实现不同的逻辑,所以我们使用的是模板模式方法。

模板模式有如下功能:

  1.能够解决代码冗余问题。在例子中,PassengerbyAir ,PassengerbyCoach ,PassengerbyTrain 没有必要再去实现buyTickey()celebrate()方法了。

  2.易于扩展。我们通过创建新类,实现可定制化的方法就可以扩展功能。如果有人坐船回家,加入PassengerByBoat类并实现travel()方法即可。

  3. 父类提供了算法的框架,控制方法执行流程,而子类不能改变算法流程,子类方法调用由父类模板方法决定。

 4.父灰可以把那些重要的不允许改变的方法屏蔽掉,不让子类去重写。我们可以声明这些为private final.

 

 

 

原文地址:https://www.cnblogs.com/andgoo/p/2569618.html