软件构造思考5:策略模式/Visitor模式/模板模式/装饰器模式

1.策略模式:

当我们实现一个方法时,我们可能有多种情况,那客户端怎么进行灵活选择呢?

一种是比较麻烦的方法,我们在这个类中多写几个实现方法,在客户端分情况调用,例如:

class Option{
	
	public Option()
	{
		
	}
	public void option1(){	
		System.out.println("1");
	}
	public void option2() {	
        System.out.println("2");
	}
	public void option3() {
        System.out.println("3");
	}
	public void option4(){
        System.out.println("4");
	}
 }

public class client{
	public static void Main()
	{
		Option first=new Option();
		first.option1();
		first.option2();
		first.option3();
		first.option4();
	}
	}

        但是这种情况对于客户端来说很麻烦,而且他的可扩展性很差,每次必须修改原本的类,违反了OCP原则,并且它需要知道很多你内部的信息,所以我们可以模板方法,使用一个接口,对接口进行继承的扩展用来完成我们所需要的方法:

interface Option{
	abstract void option();
 }
class option1 implements Option{
	@Override
	public void option()
	{
		System.out.println("1");
	}
}
class option2 implements Option{

	@Override
	public void option() {
		System.out.println("2");
		
	}
	
}
class option3 implements Option{

	@Override
	public void option() {
		System.out.println("3");
		
	}
	
}
class Use{
	public void function(Option o) {
		o.option();
	}
}

public class client{
	public static void Main()
	{
		Use u=new Use();
		u.function(new option1());
		u.function(new option2());
	}
	}

2.Visitor模式

        当我们有很多有共性的具体的类,要观察他的属性时,该怎么办?一般的做法是给每个类都加一个visit方法,让他返回需要观察的信息,但是这样很麻烦,一旦我们所需要的信息变化,我们就要重新改写这个类,所以我们可以采用Visitor模式,对特定类型的object的特定操作(visit),在运行时将 二者动态绑定到一起,该操作可以灵活更改,无需更改被visit的类。

interface show{
	abstract void visit(Books x);
	abstract void visit(Fruit x);
 }
class show1 implements show{

	@Override
	public void visit(Books s) {
		//具体方法
		
	}

	@Override
	public void visit(Fruit x) {
		//具体方法
		
	}
	
}
class show2 implements show{

	@Override
	public void visit(Books s) {
		//具体方法
		
	}

	@Override
	public void visit(Fruit x) {
		//具体方法
		
	}
	
}
interface Goods{
	public void accept(show s);
}
class Books implements Goods{
	@Override
	public void accept(show s) {
		s.visit(this);
	}
}
class Fruit implements Goods{
	@Override
	public void accept(show s) {
		s.visit(this);
	}
}

public class client{
	public static void Main()
	{
		Goods goods=new Books();
		goods.accept(new show1());
		goods.accept(new show2());
	}
	}

3.模板模式:

       当我们实现一个ADT, 它做事情的步骤一样,但具体方法不同,我们可以采用模板方法,父类定义骨架,子类实现某些细节。

public abstract class HavingDinnerTemplate {    
    //具体的整个固定流程,使用final防止子类改写
    public final void step(){
   
        this.varietyofdishes();
        this.dessert();
    }
    public  void preparation()
    {
        System.out.println("洗手");
    }

   //具体操作交由子类实现
     //菜品
    public abstract void varietyofdishes();
     //甜点
    public abstract void dessert ();
}


//西红柿炒鸡蛋
public class dish1 extends HavingDinnerTemplate{
    @Override
    public void varietyofdishes() {
        System.out.println("西红柿炒鸡蛋");
    }
    @Override
    public void dessert() {
        System.out.println("牛奶蛋糕");
    }
//红烧肉
public class dish2 extends HavingDinnerTemplate{
    @Override
    public void varietyofdishes() {
        System.out.println("红烧肉");
    }
    @Override
    public void dessert() {
        System.out.println("芒果冰沙");
    }
}

public class Main {
    public static void main(String[] args) {
        HavingDinnerTemplate eggsWithTomato = new dish1();
        eggsWithTomato.varietyofdishes();
        System.out.println("-----------------------------");
        HavingDinnerTemplate bouilli = new dish2();
        bouilli.varietyofdishes();
    }
}

4.装饰器模式

        当我们使用继承时,用每个子类实现不同的特性,但是要是我们想要混合使用这些特性时,我们该怎么办呢?一般想法是我用那个我就就继承谁呗,但是当我们要使用的特性很多时,就会产生组合爆炸!

        我们使用装饰器模式可以避免产生上述问题,例如下图:

interface IStack {
void push(int e);
int pop();
}
public class Stack implements IStack {
public Stack() {...}
public void push(int e) {
...
}
public int pop() {
...
}
...
}

public abstract class StackDecorator implements IStack {
protected final IStack stack;
public StackDecorator(Stack stack) {
this.stack = stack;
}
public void push(int e) {
stack.push(e);
}
public int pop() {
return stack.pop();
}
...
}
public class UndoStack extends StackDecorator implements IStack {
private final UndoLog log = new UndoLog();
public UndoStack(Stack stack) { 
super(stack); 
}
public void push(Item e) {
log.append(UndoLog.PUSH, e);
super.push(e);
}
public void undo() {
//implement decorator behaviors on stack
}
...
}

         我们在StackDecorator类中加入了Stack成员变量,这时候我们只要在初始化时加入我们要组合的特性所在的class,就可以完成我们想要的特性组合,例如我们可以使用

IStack s = new Stack();

IStack t = new SecureStack( new SynchronizedStack( new UndoStack(s))完成组合。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值