慕課網_《模式的祕密之策略模式》學習總結

時間:2017年08月31日星期四
說明:本文部份內容均來自慕課網。@慕課網:http://www.imooc.com
教學源碼:https://github.com/zccodere/s...
學習源碼:https://github.com/zccodere/s...git

第一章:策略模式簡介

1-1 簡介

課程大綱github

什麼是策略模式
策略模式如何實現
策略模式總結篇
實例案例分享

平常生活中的策略算法

World文檔中的排版佈局
購物支付過程當中選擇支付渠道

案例示意圖編程

clipboard.png

策略模式定義架構

策略模式將可變的部分從程序中抽象分離成算法接口,
在該接口下分別封裝一系列算法實現並使他們能夠相互替換,
從而致使客戶端程序獨立於算法的改變。

第二章:策略模式應用

2-1 虛擬應用

模擬應用背景框架

經過代碼來實現策略模式,經過開發與重構虛擬應用
使用策略模式實現,在不變動代碼框架的前提下
不斷的擁抱需求的變化,從而知足客戶需求

項目背景:鴨子應用ide

clipboard.png

2-2 原有功能

代碼編寫工具

1.編寫Duck類佈局

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 超類,全部的鴨子都要繼承此類,抽象了鴨子的行爲:顯示和鳴叫
 * @author zc
 * @version 1.0 2017-08-31
 */
public abstract class Duck {
    
    /**
     * 鴨子發出叫聲,通用行爲,由超類實現
     */
    public void quack(){
        System.out.println("嘎嘎嘎");
    }
    
    /**
     * 顯示鴨子的外觀,鴨子的外觀各不相同,聲明爲abstract,由子類實現
     */
    public abstract void display();
}

2.編寫MallardDuck類學習

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 綠脖子的鴨子
 * @author zc
 * @version 1.0 2017-08-31
 */
public class MallardDuck extends Duck {

    @Override
    public void display() {
        System.out.println("個人脖子是綠色的");
    }
}

3.編寫RedheadDuck類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 紅色頭的鴨子
 * @author zc
 * @version 1.0 2017-08-31
 */
public class RedheadDuck extends Duck {

    @Override
    public void display() {
        System.out.println("個人頭是紅色的");
    }
}

2-3 增長功能

在原有功能的基礎上新增飛行的功能

使用繼承:父類統一實現
定義抽象方法:由子類本身實現
使用組合:複合優先於繼承:多用組合,少用繼承

繼承優缺點

繼承是重用代碼的利器
但繼承並不老是最好的工具

什麼是組合

在類中增長一個私有域,引用另外一個已有的類的實例,經過調用引用實例的方法從而得到新的功能,這種設計被稱做組合(或複合)。

使用組合增長飛行功能

實現:將飛行行爲抽象爲接口,在父類中持有該接口,並由該接口代理飛行行爲
優勢:足夠靈活;複用代碼,更易於維護
缺點:策略類會增多;全部策略類都須要對外暴露

2-4 實現功能

代碼編寫

1.編寫FlyingStrategy類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 策略接口,實現鴨子的飛行行爲
 * @author zc
 * @version 1.0 2017-08-31
 */
public interface FlyingStrategy {
    
    /**
     * 飛行行爲的方法
     */
    void performFly();
    
}

2.編寫FlyWithWin類

package com.myimooc.designpattern.c7strategy.impl;

import com.myimooc.designpattern.c7strategy.FlyingStrategy;

/**
 * @title 策略模式
 * @describe 實現鴨子的飛行行爲,用翅膀飛行的類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class FlyWithWin implements FlyingStrategy{

    @Override
    public void performFly() {
        System.out.println("振翅高飛");
    }
}

3.修改Duck類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 超類,全部的鴨子都要繼承此類,抽象了鴨子的行爲:顯示和鳴叫
 * @author zc
 * @version 1.0 2017-08-31
 */
public abstract class Duck {
    
    /**
     * 鴨子發出叫聲,通用行爲,由超類實現
     */
    public void quack(){
        System.out.println("嘎嘎嘎");
    }
    
    /**
     * 顯示鴨子的外觀,鴨子的外觀各不相同,聲明爲abstract,由子類實現
     */
    public abstract void display();
    
    // 組合進飛行的策略接口
    private FlyingStrategy flyingStrategy;

    public void setFlyingStrategy(FlyingStrategy flyingStrategy) {
        this.flyingStrategy = flyingStrategy;
    }
    
    /**
     * 鴨子的飛行功能
     */
    public void fly(){
        // 由飛行策略接口執行飛行的動做
        flyingStrategy.performFly();
    }
}

4.修改MallardDuck類

package com.myimooc.designpattern.c7strategy;

import com.myimooc.designpattern.c7strategy.impl.FlyWithWin;

/**
 * @title 策略模式
 * @describe 綠脖子的鴨子
 * @author zc
 * @version 1.0 2017-08-31
 */
public class MallardDuck extends Duck {
    
    public MallardDuck() {
        super();
        super.setFlyingStrategy(new FlyWithWin());
    }
    
    @Override
    public void display() {
        System.out.println("個人脖子是綠色的");
    }
}

5.修改RedheadDuck類

package com.myimooc.designpattern.c7strategy;

import com.myimooc.designpattern.c7strategy.impl.FlyWithWin;

/**
 * @title 策略模式
 * @describe 紅色頭的鴨子
 * @author zc
 * @version 1.0 2017-08-31
 */
public class RedheadDuck extends Duck {

    public RedheadDuck() {
        super();
        super.setFlyingStrategy(new FlyWithWin());
    }
    
    @Override
    public void display() {
        System.out.println("個人頭是紅色的");
    }
}

6.編寫DuckTest類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 測試類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class DuckTest {
    
    public static void main(String[] args) {
        System.out.println("測試鴨子程序");
        System.out.println("*************************");
        
        Duck duck = null;
//        duck = new MallardDuck();
//        duck = new RedheadDuck();
//        duck = new RubberDuck();
//        duck = new BigYellowDuck();
        duck = new SpaceDuck();
        
        duck.display();
        duck.quack();
        duck.fly();
        
        System.out.println("*************************");
        System.out.println("測試程序完畢");
    }
    
}

2-5 複用代碼

業務場景

須要增長橡膠鴨、大黃鴨,它們都有一個共同的特色,不會飛行。
不會飛行也是一種飛行行爲,因此能夠經過良好的抽象複用代碼。

代碼編寫

1.編寫FlyNoWay類

package com.myimooc.designpattern.c7strategy.impl;

import com.myimooc.designpattern.c7strategy.FlyingStrategy;

/**
 * @title 策略模式
 * @describe 實現鴨子的飛行行爲,不會飛行的策略類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class FlyNoWay implements FlyingStrategy {

    @Override
    public void performFly() {
        System.out.println("我不會飛行!");
    }

}

2.編寫RubberDuck類

package com.myimooc.designpattern.c7strategy;

import com.myimooc.designpattern.c7strategy.impl.FlyNoWay;

/**
 * @title 策略模式
 * @describe 橡膠鴨
 * @author zc
 * @version 1.0 2017-08-31
 */
public class RubberDuck extends Duck{
    
    public RubberDuck() {
        super();
        super.setFlyingStrategy(new FlyNoWay());
    }
    
    @Override
    public void display() {
        System.out.println("我全身發黃,嘴巴很紅");
    }

    @Override
    public void quack() {
        System.out.println("嘎~嘎~嘎~");
    }
}

3.編寫BigYellowDuck類

package com.myimooc.designpattern.c7strategy;

import com.myimooc.designpattern.c7strategy.impl.FlyNoWay;

/**
 * @title 策略模式
 * @describe 大黃鴨
 * @author zc
 * @version 1.0 2017-08-31
 */
public class BigYellowDuck extends Duck{
    
    public BigYellowDuck() {
        super();
        super.setFlyingStrategy(new FlyNoWay());
    }
    
    @Override
    public void display() {
        System.out.println("我身體很大,全身黃黃");
    }
}

4.修改DuckTest類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 測試類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class DuckTest {
    
    public static void main(String[] args) {
        System.out.println("測試鴨子程序");
        System.out.println("*************************");
        
        Duck duck = null;
//        duck = new MallardDuck();
//        duck = new RedheadDuck();
//        duck = new RubberDuck();
//        duck = new BigYellowDuck();
        duck = new SpaceDuck();
        
        duck.display();
        duck.quack();
        duck.fly();
        
        System.out.println("*************************");
        System.out.println("測試程序完畢");
    }
    
}

2-6 新增種類

業務場景

如今又需增長太空鴨,太空鴨不能本身飛行,須要藉助先進的科學技術。

1編寫FlyWithRocket類

package com.myimooc.designpattern.c7strategy.impl;

import com.myimooc.designpattern.c7strategy.FlyingStrategy;

/**
 * @title 策略模式
 * @describe 實現鴨子的飛行行爲,使用火箭飛行策略類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class FlyWithRocket implements FlyingStrategy {

    @Override
    public void performFly() {
        System.out.println("用火箭在太空遨遊");
    }
}

2.編寫SpaceDuck類

package com.myimooc.designpattern.c7strategy;

import com.myimooc.designpattern.c7strategy.impl.FlyWithRocket;

/**
 * @title 策略模式
 * @describe 太空鴨
 * @author zc
 * @version 1.0 2017-08-31
 */
public class SpaceDuck extends Duck {

    public SpaceDuck() {
        super();
        super.setFlyingStrategy(new FlyWithRocket());
    }
    
    @Override
    public void display() {
        System.out.println("我頭戴宇航盔");
    }
    
    @Override
    public void quack() {
        System.out.println("我經過無線電與你通訊");
    }

}

3.修改DuckTest類

package com.myimooc.designpattern.c7strategy;

/**
 * @title 策略模式
 * @describe 測試類
 * @author zc
 * @version 1.0 2017-08-31
 */
public class DuckTest {
    
    public static void main(String[] args) {
        System.out.println("測試鴨子程序");
        System.out.println("*************************");
        
        Duck duck = null;
//        duck = new MallardDuck();
//        duck = new RedheadDuck();
//        duck = new RubberDuck();
//        duck = new BigYellowDuck();
        duck = new SpaceDuck();
        
        duck.display();
        duck.quack();
        duck.fly();
        
        System.out.println("*************************");
        System.out.println("測試程序完畢");
    }
    
}

第三章:策略模式總結

3-1 總結

策略模式中的設計原則

找出應用中須要變化的部分,把他們獨立出來,不要和那些不須要變化的代碼混在一塊兒
面向接口編程,而不是面向實現編程
多用組合,少用繼承

策略模式的實現

經過分離變化得出的策略接口Strategy
Strategy接口的實現類
客戶程序中有一個Strategy
在客戶程序中選擇和組裝正確的Strategy實現類

策略模式的優勢

使用了組合,使架構更加靈活
富有彈性,能夠較好的應對變化(開閉原則)
更好的代碼複用性(相對於繼承)
消除大量的條件語句

策略模式的缺點

客戶代碼須要瞭解每一個策略實現的細節
增長了對象的數目
全部策略類都須要對外暴露

策略模式的適用場景

許多相關的類僅僅是行爲差別
運行時選取不一樣的算法變體
經過條件語句在多個分支中選取其中一個
相關文章
相關標籤/搜索