Java设计模式 ----- 模板设计模式

     模板模式便是通过定义一个模板(结构、框架、原型),在之后的工作便是对其进行充实、完善实际所需。 

     模板采用抽象类来定义,公共的结构化逻辑需要在抽象基类中定义,只将非公共类的部分逻辑抽象成方法,留在子类充实实现。

    

     用生活中的两个例子来说:泡茶和煮咖啡。

            泡茶步骤:1.将水煮沸 2.浸泡茶包 3.将茶倒入杯中 4.加柠檬

            煮咖啡步骤:1.将水煮沸 2.冲泡咖啡 3.将咖啡倒入杯中 4.加糖和牛奶

    

     从上面步骤可以看出无论是泡茶还是煮咖啡过程都是大致相似的,甚至1、2步骤是完全相同的,而3、4步骤只是冲泡和加入的调料有所不同,所以根据模板模式的定义,将1、2相同的这两部分放在超类中,可以被两个子类所共用,将步骤3、4声明为抽象方法,留给子类充实。回过头来我们仔细想想既然整个过程大致相似,只是放入的原料以及加入的辅料不同,则我们亦可以将整个过程抽象化。

     其类图如下:

代码如下:

     实现抽象基类,为所有子类提供模板

import java.util.Scanner;
abstract class CaffeineBeverage{
	//冲泡咖啡
	//用同一个prepareRecipe()方法处理茶和咖啡。
	//声明为final是因为不希望子类覆盖方法!
	final void prepareRecipe(){
		boilWater();
		brew();
		pourIncup();
		addCondiments();
		}
		//处理方法不同的,声明为抽象方法,留给子类实现
		abstract void brew();
		abstract void addCondiments();
		
		public void boilWater(){
			System.out.println("将水煮沸");
			}
			public void pourIncup(){
				System.out.println("将饮料倒进杯子中");
			}
		}

        其中brew()与addCondiments()需要具体在子类中实现,需声明为抽象方法。

        抽象方法具体在咖啡和茶子类中的实现

//茶子类
class Tea extends CaffeineBeverage{
	void brew(){
		System.out.println("泡茶");
	}
	void addCondiments(){
		System.out.println("加柠檬");
	}
}
//咖啡子类
class Coffee extends CaffeineBeverage{
	void brew(){
		System.out.println("泡咖啡");
	}
	void addCondiments(){
		System.out.println("加糖和牛奶");
	}

       在实现第四步骤时,因为在选择添加调料时每个人都有自己的喜好,那么在实现这一个性化需求时,需要提供一个钩子函数(默认不做事的方法,子类视情况决定要不要覆盖),具体到每个场景,使用不同的钩子函数 。

       钩子函数的具体实现

//if条件判断钩子函数的调用
if(customerWantsaddCondiments()){
	addCondiments();
        }
boolean customerWantsaddCondiments(){
	return true;
        }
public boolean customerWantsaddCondiments(){
	String answer = getUserInput();
	if(answer.equals("y")){
		return true;
	}else{
		return false;
	}
private String getUserInput(){
        String answer = null;
        System.out.println("您想要加牛奶和糖吗(y/n)");
	Scanner scanner = new Scanner(System.in);
	answer = scanner.nextLine();
	return answer;
	}

           测试类

private String getUserInput(){
        String answer = null;
        System.out.println("您想要加牛奶和糖吗(y/n)");
		Scanner scanner = new Scanner(System.in);
		answer = scanner.nextLine();
		return answer;
	}

           究竟模板方法能带给我们什么呢?

       

    

                                                                                                                                                                                                       

发布了19 篇原创文章 · 获赞 16 · 访问量 3653

猜你喜欢

转载自blog.csdn.net/O9A0MA/article/details/86367313