groovy 閉包【命令模式】

Java編程世界,有兩個設計模式又簡單、又經常使用,並且實現方式也很類似,這就是命令模式和策略模式。算法

有關這兩個模式的講解,在網絡上真是汗牛充棟,你們能夠隨便搜索一下,就是一大堆。編程

能夠簡單的說,命令模式就是對行爲或者命令的封裝,而策略模式則是對算法的封裝。對於行爲或是說命令,還有算法,在編碼的實現上都是要用到方法來實現的。設計模式

因此,咱們能夠簡單的把這兩種模式這樣理解:它們都是要對方法進行操做,像使用類和對象那樣操做,好比傳遞和循環,而在Java等面向對象的編程語言中,方法是不能獨立操做的,它必須依附於一個類和對象,而不能直接操做一個方法。基於這樣的緣由,咱們設計了命令模式和策略模式來解決上面的問題。具體的實現就是抽象出一個接口來操做這些方法,而接口的實現就是用來具體實現一個個的行爲或策略;而咱們就是經過引用接口來達到引用這些方法的目的。網絡

下面舉一個簡單的例子來講明上面的理解。好比,咱們要控制一盞燈的開關,利用命令模式能夠設計以下。閉包

咱們先抽象出一個接口來:編程語言

 

public interface Light {測試

   

    public void common();編碼

 

}spa

 

這個接口是咱們可以引用開關動做的基礎,下面咱們來實現燈的開關動做:設計

 

public class LightOn implements Light {

 

    public void common() {

       System.out.println("light turn on...");

    }

 

}

 

上面是開燈的動做,咱們接着寫關燈的動做:

 

public class LightOff implements Light {

 

    public void common() {

       System.out.println("light turn off...");

    }

 

}

 

 

接着就是對上面的抽象的使用:

 

public class LightAction {

 

    public static void main(String[] args) {

      

       Light[] actions= new Light[]{new LightOn(),new LightOff(),new LightOn(),newLightOff()};

      

       for(int i=0;i<actions.length;i++)

       {

           actions[i].common();

       }

 

    }

 

}

 

運行結果爲:

 

light turn on...

light turn off...

light turn on...

light turn off...

 

經過上面的例子,能夠看到,所謂命令模式,就是咱們但願將形如開燈和關燈這樣的動做進行組合或者傳遞,而開燈和關燈在代碼中對應爲方法,在面向對象的編程中,方法是不能直接進行組合或傳遞的,因此咱們把開燈和關燈的方法依附於兩個類「LightOn」和「LightOff」上。同時,爲了方便方法之間的組合執行和傳遞,它們必須實現相同的接口,只有這樣,「actions[i].common()」這樣的語句才能正確執行。

經過了上面的分析,咱們能夠得出結論:在Java語言中使用命令模式和策略模式,徹底是因爲面向對象的語言中不能獨立存在方法而致使的,同時方法也不能直接被傳遞,而必須依賴於類。

明白了上面的道理,咱們就能夠想到,若是一個語言中的方法能夠直接被看成對象來使用和傳遞,咱們就能夠拋開命令模式和策略模式,而直接使用方法來操做。這就比命令模式和策略模式來得更爲直接和簡單易懂。

而咱們的Groovy語言正是存在這樣的特色,咱們都知道,雖然在Groovy語言中,方法也不能直接被用來傳遞和使用,可是有一種方法的變形能夠直接被看成對象來使用,這就是閉包。

下面,咱們來看看閉包是如何實現策略模式的。首先,咱們設計一個類來實現全部的方法:

class Light {

   

    def turnOn()

    {

       println 'light turn on...'

    }

   

    def turnOff()

    {

       println 'light turn off...'

    }

 

}

 

 

而後,咱們就能夠實現命令模式了:

 

      def light = new Light()

     

      def lightOn = light.&turnOn

     

      def lightOff = light.&turnOff

     

      def commons = [lightOn,lightOff,lightOn,lightOff]

     

      commons.each{

         it.call()

  }

 

運行結果爲:

 

light turn on...

light turn off...

light turn on...

light turn off...

 

能夠看到,上面的代碼比起Java語言中的命令模式實現起來要簡單得多,但功能倒是同樣的。

還有,模式的一個重要功能是它良好的擴展性。上面的命令模式就擁有良好的擴展性,好比咱們但願增長一個方法來調節燈的亮度,使得更亮一些。命令模式在新增一個方法的時候,不會去修改已經寫好的類,這樣會致使已經寫好的代碼須要從新測試。咱們只需增長一個新的類:

 

public class Lighter implements Light {

 

    public void common() {

      

       System.out.println("make it lighter...");

      

    }

 

}

 

 

增長了新的類之後,咱們固然就能夠照常使用它了:

 

 

       Light[] actions= new Light[]{new LightOn(),new Lighter(),new LightOff()};

      

       for(int i=0;i<actions.length;i++)

       {

           actions[i].common();

       }

   

 

運行結果爲:

 

light turn on...

make it lighter...

light turn off...

 

那麼,咱們在Groovy語言中使用閉包來實現的命令模式是否也擁有良好的擴展性呢?咱們的回答是:固然,它也有良好的擴展性。下面咱們來看閉包的命令模式的擴展性的例子。

首先,咱們能夠新增一個類來實現這個新的行爲:

 

class Lighter {

   

    def turnLighter()

    {

       println 'make it lighter...'

    }

 

}

 

這是一個新的類,固然沒有修改到原來的類「Light」。下面,咱們來看怎麼使用它:

 

     

       def light = new Light()

     

      def lightOn = light.&turnOn

     

      def lightOff = light.&turnOff

     

      def l = new Lighter()

      

       def lighter = l.&turnLighter

     

      def commons = [lightOn,lighter,lightOff]

     

      commons.each{

         it.call()

      }

   

 

 

運行結果爲:

 

light turn on...

make it lighter...

light turn off...

 

咱們能夠看到,在Groovy語言中,使用閉包實現的命令模式擴展起來也是同樣的方便,它甚至能夠更方便,咱們能夠不用新增類,即「Lighter」都不須要。請看下面的編碼:

     

       def light = new Light1()

     

      def lightOn = light.&turnOn

     

      def lightOff = light.&turnOff

 

       def lighter = {

           println 'make it lighter...'

       }

     

      def commons = [lightOn,lighter,lightOff]

     

      commons.each{

         it.call()

      }

   

 

運行結果爲:

 

light turn on...

make it lighter...

light turn off...

 

 

在上面的編碼中,咱們沒有新增任何的類,卻也實現了對燈的動做的擴展,這就是使用閉包的方便之處。

 

固然,咱們上面的例子都是以命令模式來說解的,其實策略模式也是同樣的道理,只不過命令模式是對行爲或動做的封裝,而策略模式是對算法的封裝,有興趣的你,不妨使用閉包來實現策略模式看看。

相關文章
相關標籤/搜索