First they ignore you
then they ridicule you
then they fight you
then you win
    -- Mahatma Gandhi
Chinese => English     英文 => 中文             
随笔-219  评论-1047  文章-0  trackbacks-0
Groovy和Java都习惯使用null来表示“空”这一概念,而对null的操作将引发NullPointerException(简写为NPE),进而影响系统的健壮性。为了避免NPE,Option模式应运而生,通过Option类型来标识NPE风险,其使用None对象表示“空”,并使用Some对象表示“非空”且持有值对象,最终提升了系统健壮性。

1.使用Gradle管理项目,通过“gradle init --type groovy-library”生成项目结构
<项目根目录>
│  build.gradle
│  gradlew
│  gradlew.bat
│  settings.gradle

├─.gradle
│  └─2.12
│      └─taskArtifacts
│              cache.properties
│              cache.properties.lock
│              fileHashes.bin
│              fileSnapshots.bin
│              outputFileStates.bin
│              taskArtifacts.bin

├─gradle
│  └─wrapper
│          gradle-wrapper.jar
│          gradle-wrapper.properties

└─src
    ├─main
    │  └─groovy
    │          Library.groovy
    │
    └─test
        └─groovy
                LibraryTest.groovy

2.编辑build.gradle,管理项目依赖
/*
 * This build file was auto generated by running the Gradle 'init' task
 * by '山风小子' at '16-8-13 下午3:03' with Gradle 2.12
 *
 * This generated file contains a sample Groovy project to get you started.
 * For more details take a look at the Groovy Quickstart chapter in the Gradle
 * user guide available at 
https://docs.gradle.org/2.12/userguide/tutorial_groovy_projects.html
 
*/

// Apply the groovy plugin to add support for Groovy
apply plugin: 'groovy'

// In this section you declare where to find the dependencies of your project
repositories {
    // Use 'jcenter' for resolving your dependencies.
    
// You can declare any Maven/Ivy/file repository here.
    maven { url 'https://dl.bintray.com/danielsun1106/generic/' } // 新增代码
    jcenter()
}

// In this section you declare the dependencies for your production and test code
dependencies {
    // We use the latest groovy 2.x version for building this library
    compile 'org.codehaus.groovy:groovy-all:2.4.7' // 新增代码

    compile 'com.groovyhelp:groovy-option-support:1.0.1' // 新增代码
}

// 新增代码
task run(type: JavaExec, dependsOn: 'classes') {
    classpath = sourceSets.main.runtimeClasspath
    main = "Library"
}

3.至此环境已准备完毕,编辑src/main/groovy/Library.groovy,并执行“gradle run”以开始我们Option模式体验之旅
/*
 * This Groovy source file was auto generated by running 'gradle buildInit --type groovy-library'
 * by '
山风小子' at '16-8-13 下午3:03' with Gradle 2.12
 *
 * @author 
山风小子, @date 16-8-13 下午3:03
 
*/
class Library {
    public static void main(String[] args) {
            println "*********** Option模式体验之旅 *************"
                
                def m = new HashMap() {
                    {
                        putAll([a: 1, b: 2, c: 3]); // 初始化
                    }

                    @Override
                    public Option get(Object key) { // 覆盖HashMap的get方法,以返回Option对象,该对象通过Option.$new方法创建
                        return Option.$new(super.get(key));
                    }
                }

                // 由于get方法已通过Option标示了NPE风险,所以调用者有意识地使用$switch方法来分情况处理
                m.get('b').$switch {
                        // 如果get的返回结果为Some(即“非空”),则执行该闭包内容
                    println "b对应的值: $it";
                } {
                    // 如果get的返回结果为None(即“空”),则执行该闭包内容
                    println "找不到b对应的值";
                }
                
                // $switch的另外一种使用方式,与上述方式相似
                println 'b的查找结果:' + m.get('b').$switch { return it /* 返回b对应的值 */ } { return 0 /* 如果没有找到b,则返回0 */ }
                
                // 尝试查找一个不存在的key(比如d)
                m.get('d').$switch {
                    println "d对应的值: $it";
                } {
                    println "找不到d对应的值";
                }
                
                // 虽然是Option对象,但可以将其视作原始对象并访问其方法及属性
                println """m.get('a').intValue()执行结果: ${m.get('a').intValue()}"""
                
    }
}

执行结果:
D:\_LAB>gradle run
:compileJava UP-TO-DATE
:compileGroovy
:processResources UP-TO-DATE
:classes
:run
*********** Option模式体验之旅 *************
b对应的值: 2
b的查找结果:2
找不到d对应的值
m.get('a').intValue()执行结果: 1

BUILD SUCCESSFUL

Total time: 7.803 secs

更多例子可以查看:https://github.com/danielsun1106/groovy-option-support/blob/master/src/test/groovy/groovy/lang/OptionTest.groovy
groovy-option-support项目主页:https://github.com/danielsun1106/groovy-option-support

posted on 2016-08-13 16:17 山风小子 阅读(1844) 评论(0)  编辑  收藏 所属分类: Groovy & Grails
317| 164| 243| 731| 468| 557| 521| 366| 395| 954|