面向复用的软件设计模式(2)

文章目录

  • 面向复用的软件设计模式(2)——行为模式
    • 三种行为模式
    • 策略模式
      • 解决的问题
      • 实现方法
      • 一个策略模式的例子
    • 模板方法
      • 解决的问题
      • 实现方法
      • 一个模板方法的例子
    • 迭代器模式
      • 解决的问题
      • 实现方法
      • 几个角色

面向复用的软件设计模式(2)——行为模式

三种行为模式

  • 策略模式(Stategy)
    • 策略允许在运行时即时选择一系列算法中的一个。
  • 模板方法(Template method)
    • 模板方法将算法的骨架定义为抽象类,允许其子类提供具体行为。
  • 迭代器模式(Iterator)
    • 迭代器模式按顺序访问对象的元素,而不暴露其底层表示。

策略模式

解决的问题

  • 对于特定的任务,存在多种算法完成,但是调用者(客户端)可以根据动态的上下文环境进行选择和切换。比如对于一个列表的排序,可以使用冒泡排序、快速排序等多种算法。

实现方法

  • 为算法创建一个接口,每个算法使用一个类来实现这个接口,客户端针对接口编写程序。
  • 好处:可以更方便地扩展新的算法并且能够将算法与客户端的上下文环境隔离开。
  • 各个模块之间的关系:
    面向复用的软件设计模式(2)_第1张图片

一个策略模式的例子

客户端根据上下文选择两种付款方式:信用卡和PayPal。

public interface PaymentStrategy{
	public void pay(int amount);
}

信用卡付款:

public class CreditCardStrategy implements PaymentStrategy{
	private String name;
	private String cardNumber;
	private String cvv;
	private String dateOfExpiry;
	public CreditCardStrategy(String nm, String ccNum, String cvv, String expiryDate){
		this.name=nm;
		this.cardNumber=ccNum;
		this.cvv=cvv;
		this.dateOfExpiry=expiryDate;
	}
	@Override
	public void pay(int amount){
		System.out.println(amount +" paid with credit card");
	}
}

PayPal付款:

public class PaypalStrategy implements PaymentStrategy{
	private String emailId;
	private String password;
	public PaypalStrategy(String email, String pwd){
		this.emailId=email; this.password=pwd;
	}
	@Override
	public void pay(int amount){
		System.out.println(amount + " paid using Paypal.");
	}
}
public class ShoppingCart
{
	...
	public void pay(PaymentStrategy paymentMethod){
		int amount=calculateTotal();
		paymentMethod.pay(amount);
	}
}

客户端代码:

public class ShoppingCartTest{
	public static void main(String[] args){
		ShoppingCart cart=new ShoppingCart();
		Item item1=new Item("1234",10);
		Item item2=new Item("5678",40);
		cart.addItem(item1);
		cart.addItem(item2);
		//pay by paypal
		cart.pay(new PaypalStrategy("[email protected]", "mypwd")); 
		//pay by credit card
		cart.pay(new CreditCardStrategy(“Alice", "1234", "786", "12/18"));
	}
}

模块间的关系:
面向复用的软件设计模式(2)_第2张图片

模板方法

解决的问题

  • 不同的客户端具有相同的算法步骤,但是每个步骤的具体实现不同,即一个算法具有不变的部分也有可以自定义的部分。比如执行测试用例测试套件、开放,阅读,编写不同类型的文件等。

实现方法

  • 一个算法的通常步骤在一个抽象父类中定义,自定义部分用抽象方法的定义来代表,子类中进行各个步骤的具体实现。
  • 模块间的关系:
    面向复用的软件设计模式(2)_第3张图片

一个模板方法的例子

制作两种不同的电脑,步骤相同,但是每一步的具体实现不同。

public abstract class PCBuilder{
	protected abstract void BuildModel();
	protected abstract void InstallCPU();
	protected abstract void InstallOS();
	void BuildPC(){
	//通用逻辑
	BuildModel();
	InstallCPU();
	InstallOS();
	}
}
public class LenovoBuilder extends PCBuilder{
	protected void BuildModel(){
		System.out.println("Building Lenovo Model");
	}
	protected void InstallCPU(){
		System.out.println("Installing Intel CPU");
	}
	protected void InstallOS(){
		System.out.println("Installing Windows10 OS");
	}
}
public class DellBuilder extends PCBuilder{
	protected void BuildModel(){
		System.out.println("Building Dell Model");
	}
	protected void InstallCPU(){
		System.out.println("Installing AMD CPU");
	}
	protected void InstallOS(){
		System.out.println("Installing Ubuntu OS");
	}
}

迭代器模式

解决的问题

  • 客户端需要用统一的,与元素类型无关的方式来访问容器中的所有元素

实现方法

  • 面向迭代的策略模式
  • 隐藏容器的内部实现
  • 使用统一的接口支持多种遍历策略
  • 更改容器类型更简单,模块之间能够在程序内进行交流

几个角色

  • Iterator interface:定义了所有的遍历集合所需要的方法。
  • ConcreteIterator:实现Iterator接口,实现迭代功能。
  • Aggregate interface:获取迭代器对象的接口。
  • ConcreteAggregate class:是西安迭代器对象的获取
  • 角色间的关系:
    面向复用的软件设计模式(2)_第4张图片

你可能感兴趣的:(java,设计模式)