策略模式介紹以及headfirst上的兩個例項
定義:策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使他們可以相互替換,讓演算法獨立於使用它的客戶而獨立變化。
分析下定義,策略模式定義和封裝了一系列的演算法,它們是可以相互替換的,也就是說它們具有共性,而它們的共性就體現在策略介面的行為上,另外為了達到目的,也就是說讓演算法獨立於使用它的客戶而獨立變化,我們需要讓客戶端依賴於策略介面。
策略模式的優缺點:
優點:
1、結構清晰,把策略分離成一個個單獨的類「替換了傳統的 if else」
2、程式碼耦合度降低,安全性提高「各個策略的細節被遮蔽」
缺點:
1、客戶端必須要知道所有的策略類,否則你不知道該使用那個策略,所以策略模式適用於提前知道所有策略的情況下
2、增加了類的編寫,本來只需要 if else 即可「但是這是所有模式和架構的通病」
策略模式類圖:
下面來看兩個經典的案例:
1.headfirst設計模式一書中的鴨子例項
Duck.java
package StrategyPattern;
/**
* 鴨子超類
*/
public abstract class Duck {
protected FlyBehavior flyBehavior;
protected QuackBehavior quackBehavior;
public Duck() {
}
public abstract void display();
public void performFly () {
flyBehavior.fly();
}
public void perormQuack() {
quackBehavior.quack();
}
public void swim() {
System.out.println("All ducks float,even decoys!");
}
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBehavior (QuackBehavior qb) {
quackBehavior = qb;
}
}
FlyBehavior.java
package StrategyPattern;
/**
* 實現飛行介面的類
*/
public interface FlyBehavior {
void fly();
}
FlyNoWay.java
package StrategyPattern;
/**
* 不能飛
*/
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("I can't fly!");
}
}
FlyRocketPowered.java
package StrategyPattern;
/**
* 用火箭飛
*/
public class FlyRocketPowered implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying with a rocket!");
}
}
FlyWithWings.java
package StrategyPattern;
/**
* 用翅膀飛
*/
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying!");
}
}
MallardDuck.java
package StrategyPattern;
/**
* 綠頭鴨
*/
public class MallardDuck extends Duck {
public MallardDuck(){
flyBehavior = new FlyWithWings();
quackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("I'm a real Mallard duck!");
}
}
ModelDuck.java
package StrategyPattern;
/**
* 模型鴨
*/
public class ModelDuck extends Duck {
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("I'm a model duck!");
}
}
MuteQuack.java
package StrategyPattern;
/**
* 不會叫
*/
public class MuteQuack implements QuackBehavior{
@Override
public void quack()
{
System.out.println("<< Silence >>");
}
}
Quack.java
package StrategyPattern;
/**
* 呱呱叫
*/
public class Quack implements QuackBehavior{
@Override
public void quack()
{
System.out.println("Quack");
}
}
QuackBehavior.java
package StrategyPattern;
/**
* 實現發聲介面的類
*/
public interface QuackBehavior {
void quack();
}
Squeak.java
package StrategyPattern;
/**
* 吱吱叫
*/
public class Squeak implements QuackBehavior{
@Override
public void quack()
{
System.out.println("Squeak");
}
}
Test.java
package StrategyPattern;
/**
* 測試類
*/
public class Test {
public static void main(String[] args) {
//綠頭鴨
Duck mallard = new MallardDuck();
mallard.perormQuack();
mallard.performFly();
//模型鴨
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered());
model.performFly();
}
}
2.headfirst設計模式一書中策略模式課後練習之冒險遊戲
類圖設計:
AxeBehavior.java
package AdventureGame;
public class AxeBehavior implements WeaponBehavior {
@Override
public void useWeaPon() {
System.out.println("使用斧頭");
}
}
BowAndArrowBehavior.java
package AdventureGame;
public class BowAndArrowBehavior implements WeaponBehavior{
@Override
public void useWeaPon() {
System.out.println("使用弓箭");
}
}
King.java
package AdventureGame;
public class King extends Role {
public King(){
weapon=new AxeBehavior();
}
@Override
void display() {
System.out.println("這是國王");
}
}
KnifeBehavior.java
package AdventureGame;
public class KnifeBehavior implements WeaponBehavior{
@Override
public void useWeaPon() {
System.out.println("使用寶劍");
}
}
knight.java
package AdventureGame;
public class knight extends Role {
public knight(){
weapon=new SwordBehavior();
}
@Override
void display() {
System.out.println("這是騎士");
}
}
Queen.java
package AdventureGame;
public class Queen extends Role{
public Queen(){
weapon=new KnifeBehavior();
}
@Override
void display() {
System.out.println("這是皇后");
}
}
Role.java
package AdventureGame;
public abstract class Role {
WeaponBehavior weapon;
public Role(){
}
public void setWeapon(WeaponBehavior weapon) {
this.weapon = weapon;
}
abstract void display();
public void weaponWay(){
weapon.useWeaPon();
}
}
SwordBehavior.java
package AdventureGame;
public class SwordBehavior implements WeaponBehavior{
@Override
public void useWeaPon() {
System.out.println("使用匕首");
}
}
Troll.java
package AdventureGame;
public class Troll extends Role{
public Troll(){
weapon=new SwordBehavior();
}
@Override
void display() {
System.out.println("這是妖怪");
}
}
WeaponBehavior.java
package AdventureGame;
public interface WeaponBehavior {
void useWeaPon();
}
Test.java
package AdventureGame;
public class Test {
public static void main(String[] args) {
King king = new King();
king.display();
king.weaponWay();
System.out.println("更換武器以後");
king.setWeapon(new SwordBehavior());
king.weaponWay();
}
}
執行效果圖:
策略模式就先介紹到這,以後有更深的理解時再繼續補充相關內容!