`
ihuashao
  • 浏览: 4721942 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Groovy探索 自定义Range 三 自定义Range与责任链模式

阅读更多

Groovy探索 自定义Range 三 自定义Range与责任链模式

责任链模式也是我们比较常用的一种模式,我在《Groovy探索之责任链模式》中有个探索。大家也可以在网上搜索,应该有很多这方面的文章。

在这里,我们将使用自定义的Range类来实现责任链模式,使用的例子还是在《Groovy探索之责任链模式》一文中所谈到的"孙悟空大战二郎神"的这个情节。这样,我们可以把这两篇的文字结合起来看,使得我们能够对比这两种开发方式。使得我们能够深入的理解自定义Range类的使用。

在"孙悟空大战二郎神"这个情节里,重点讲述的是两人的变幻大战:其中,孙悟空分别变幻成"麻雀"、"大鹚鸟"和"雨",企图躲过二郎神的追杀;而二郎神则分别变成"鹰"、"大海鹤"和"鱼鹰"来吃掉孙悟空的相应的变幻。原文情节可以在《Groovy探索之责任链模式》看到。

这个情节使用责任链模式来实现是易于理解的,但是使用自定义的Range类来实现,则更有Groovy语言的编程风格。

现在,我们来看看使用自定义的Range类来实现的具体代码。

首先,我们要实现的还是自定义的Range类:

package range.chain;

class Base implements Comparable{

static protected types = ['cormorant','sparrow','fish']

protected int index = 0

protected type

protected getIndex()

{

this.index = this.types.indexOf(type)

}

def next()

{

Factory.getObject(types[(index+1)%types.size()])

}

def previous()

{

Factory.getObject(types[index-1])

}

int compareTo(Object other)

{

index<=>other.index

}

}

这个Base类和《Groovy探索 自定义Range 二 自定义Range类与Decorate模式》中实现的Base类没有什么区别,除了index属性的赋值不同以外。

这就提醒我们,是否可以做一个通用的自定义Range类?

接着是Factory类:

package range.chain;

class Factory {

static def getObject(type)

{

if(type == 'cormorant')

{

return new Crane()

}

else if(type == 'sparrow')

{

return new Hawk()

}

else if(type == 'fish')

{

return new Osprey()

}

}

}

这个Factory类跟前面所实现的Factory类就不一样了,因为我们的type输入的孙悟空的变幻,而各个责任模块却是二郎神的变幻,这就导致了我们的这个自定义Range在扩展上的困难。

然后,我们需要实现各个责任模块了,当然了,这些类无一例外的都要继承Base类了。我们先来看看Crane类:

package range.chain;

class Crane extends Base{

def Crane()

{

this.type = 'cormorant'

this.getIndex()

}

def fight()

{

println 'crane eat cormorant!'

}

}

这个类跟责任链模式所对应的Crane类比较起来,就更为简单一些,这也是我们增加了一个自定义Base类后得到的一点点好处。同样,我们来看看Hawk类:

package range.chain;

class Hawk extends Base{

def Hawk()

{

this.type = 'sparrow'

this.getIndex()

}

def fight()

{

println 'hawk eat sparrow!'

}

}

跟Crane类的实现一模一样,最后是Osprey类的实现:

package range.chain;

class Osprey extends Base{

def Osprey()

{

this.type = 'fish'

this.getIndex()

}

def fight()

{

println 'osprey eat fish'

}

}

现在,我们就可以来测试这种实现方式了:

def crane = new Crane()

def osprey = new Osprey()

def wukong = 'fish'

(crane..osprey).find{

Base.types[it.index] == wukong

}.fight()

运行结果为:

osprey eat fish

到现在为止,我们已经完全的实现了"孙悟空大战二郎神"的情节。比较使用责任链模式的实现和使用自定义Range类的实现,我们感觉使用自定义的Range类的实现在扩展性上要比使用责任链模式的实现要差。因为我们要扩展使用自定义的Range类的实现,我们不得不修改Factory类,而使用责任链模式的实现则不需要这样做。

但是,在使用自定义的Range类的实现中,我们的各个责任模块则更为简单,不需要往下传递责任,这是自定义Range类的功能。

除此之外,如果各个责任模块有多个方法。比如,我们的"Crane"类、"Hawk"类和"Osprey"类各自比上面的例子多了一个"descrition"方法。

则使用责任链模式的实现的客户端为:

def wukong = 'fish'

def erlangshen = new Hawk(new Osprey(new Crane(new Other())))

erlangshen.fight(wukong)

erlangshen. descrition(wukong)

这里的两个方法的调用,则责任需要传递两次,而自定义Range类的实现的客户端为:

def crane = new Crane()

def osprey = new Osprey()

def wukong = 'fish'

def erlangshen = (crane..osprey).find{

Base.types[it.index] == wukong

}

erlangshen.fight()

erlangshen.description()

而用自定义Range类的实现则只需要传递一次,似乎在算法上更为有效率。

分享到:
评论

相关推荐

    Android-AndroidRulerPicker-使用标尺从指定范围中选取数字的Android自定义视图

    ```groovy dependencies { implementation 'com.kevalpatel2106:ruler-picker:版本号' } ``` 版本号应替换为实际的库版本,可以在库的README或官方文档中找到。 接下来,在布局XML文件中添加`RulerPicker`视图: ...

    Grails权威指南

     2.2.7 范围(range)  2.3 groovy的高级特性  2.3.1 一切都是对象  2.3.2 元编程(metaprogramming)  2.3.3 生成器(builder)  2.4 本章小结 第3章 grails工程基础架构  3.1 grails...

    滑块控制件

    ```groovy implementation 'androidx.appcompat:appcompat:1.3.1' ``` 2. **在XML布局文件中添加SeekBar**:在布局文件中声明`SeekBar`并设置其属性,如ID、最小值、最大值等。 ```xml android:id="@+id/...

    Android-DateTimeRangePicker一个采用Kotlin编写的Android日期范围选择器

    3. **自定义样式**:开发者可以定制日期和时间选择器的外观,以符合应用的整体设计风格。 4. **回调机制**:组件通常会提供选择结果的回调函数,以便于开发者获取用户选定的日期和时间范围,并进行后续处理。 5. **...

    springboot整合redis实例

    如果需要自定义配置,可以在配置类中重写`RedisConnectionFactory`和`RedisTemplate`。 接下来,我们将学习如何在业务代码中使用Redis。Spring Data Redis提供了一系列的Redis操作接口,例如`BoundKeyOperations`、...

    Android中ijkPlayer播放器的简单使用

    ```groovy dependencies { implementation 'com.xiaomi.ijkplayer:ijkplayer-armv7a:最新版本号' // 其他CPU架构对应的依赖项也需要添加,例如arm64-v8a、x86等 } ``` 然后,确保在项目的AndroidManifest.xml文件...

    Grails Quick Reference 1.1

    ### Grails 快速参考指南 1.1:领域模型与数据验证 #### 领域类(Domain Class) 在Grails框架中,领域模型是应用程序的核心组件之一,用于表示数据库中的实体。Grails通过使用GORM(Groovy on Rails ORM)提供了...

    apacher_commons-lang3.1.zip

    - `Abbreviator`:用于缩短长字符串,可以自定义截断位置和替换字符。 2. **日期和时间**: - `DateUtils`:提供了对日期和时间的操作,如格式化、解析和比较。 - `DateFormatUtils`:格式化日期和时间,支持...

    Android ijkplayer的使用解析及播放器的制作

    ```groovy dependencies { implementation 'com.github.bilibili:ijkplayer-android:0.8.15' } ``` 然后,我们需要创建一个VideoView或SurfaceView来渲染视频流。ijkplayer提供了IjkMediaPlayer类,它是ijkplayer...

Global site tag (gtag.js) - Google Analytics