设计模式之策略模式

概述

策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变换独立于使用算法的客户。

涉及到的设计原则

  1. 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  2. 针对接口编程,而不是针对实现编程。
  3. 多用组合,少用继承。

UML

策略模式

  • Context:上下文角色,负责封装,屏蔽策略。
  • Strategy:抽象策略接口。
  • ConcreteStrategy:实现具体算法。

类似代理模式,只是没有共同接口。

优劣简述

优点:

  • 算法自由切换,避免封装类多重条件判断,由高层决定。
  • 符合开闭原则,扩展性好

缺点:

  • 策略类数量多,无法复用。

场景:

  • 多个类只在算法或行为上稍有不同。
  • 算法需要自由切换。
  • 算法需要屏蔽。

代码实现

多种鸭子有多种行为。

接口类及其实现类

我们把鸭子的不同行为抽象出来,比如飞的行为,但是飞有很多种,我们使用多态来实现。同时鸭子会叫,不同鸭子叫的方式可能不同,我们将使用多态来实现不同的叫声。那么至少应该有FlyBehavior和QuackBehavior两个接口。

FlyBehavior.java

public interface FlyBehavior {
	public void fly();
}

FlyNoWay.java

public class FlyNoWay implements FlyBehavior {

	@Override
	public void fly() {
		System.out.println("I can't fly.");
	}

}

FlyWithWings.java

public class FlyWithWings implements FlyBehavior {

	@Override
	public void fly() {
		System.out.println("I'm flying...");
	}

}

FlyRocketPowered.java

public class FlyRocketPowered implements FlyBehavior {

	@Override
	public void fly() {
		// TODO Auto-generated method stub
		System.out.println("I'm flying with a rocket...");
	}

}

QuackBehavior.java

public interface QuackBehavior {
	public void quack();
}

Quack.java

public class Quack implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("Quack...");
	}

}

Squeak.java

public class Squeak implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("Squeak...");
	}

}

MuteQuack.java

public class MuteQuack implements QuackBehavior {

	@Override
	public void quack() {
		// TODO Auto-generated method stub
		System.out.println("<< Silence >>");
	}

}

抽象类及其子类

假设所有的鸭子会游泳,会不同的鸣叫和飞。假设它们游泳的方式都是一样的,只有鸣叫和飞的行为不一样,这样我们就可以在抽象类中实现一样的动作,不去实现不一样的行为。以后不同鸭子只需要继承这个父类鸭子即可。

Duck.java

public abstract class Duck {
	protected FlyBehavior flyBehavior;
	protected QuackBehavior quackBehavior;
	public abstract void disPlay();
	
	public void performFly(){
		flyBehavior.fly();
	}
	
	public void performQuack(){
		quackBehavior.quack();
	}
	
	public void swim(){
		System.out.println("Swimming...");
	}

	public void setFlyBehavior(FlyBehavior flyBehavior) {
		this.flyBehavior = flyBehavior;
	}

	public void setQuackBehavior(QuackBehavior quackBehavior) {
		this.quackBehavior = quackBehavior;
	}
}

ModelDuck.java

public class ModelDuck extends Duck{

	public ModelDuck(){
		flyBehavior = new FlyNoWay();
		quackBehavior = new Quack();
	}
	@Override
	public void disPlay() {
		// TODO Auto-generated method stub
		System.out.println("I'm a ModelDuck...");
	}

}

MallardDuck.java

public class MallardDuck extends Duck{

	public MallardDuck(){
		flyBehavior = new FlyWithWings();
		quackBehavior = new Quack();
	}
	@Override
	public void disPlay() {
		// TODO Auto-generated method stub
		System.out.println("I'm a mallardDuck.");
	}

}

Duck2.java

public class Duck2 extends Duck{

	public Duck2(){
		flyBehavior = new FlyNoWay();
		quackBehavior = new Squeak();
	}
	@Override
	public void disPlay() {
		// TODO Auto-generated method stub
		System.out.println("I'm duck2...");
	}
	
}

使用

MiniDuckSimulator.java

public class MiniDuckSimulator {
	public static void main(String[] args) {
		Duck duck = new MallardDuck();
		duck.performFly();
		duck.performQuack();
		
		Duck duck2 = new Duck2();
		duck2.performFly();
		duck2.performQuack();
		
		Duck duck3 = new ModelDuck();
		duck3.performFly();
		duck3.performQuack();
		duck3.setFlyBehavior(new FlyRocketPowered());
		duck3.performFly();
	}
}
原文地址:https://www.cnblogs.com/pinnsvin/p/8573242.html