jface databinding: 创建readonly(只读)可观察对象(observable)

java与C++有一点不同:C++有const关键字,使用const关键字,用于指定一个参数、成员变量或函数是只读不可修改的,通过const参数让对象成为readonly的,可以严格禁止外部调用修改对象的内容。而java没有类似的限制,只有一个final指定变量不可以被赋值,但还是可以通过调用变量的方法任意修改变量指向的对象内部状态。也就是说,java没有像C++那样有绝对readonly的限制。 但有的时候,对象向外部提供返回的值,并不希望外部调用者修改,怎么办呢? 对于以java.util.Collection<E>为基类的对象(Map,Set,List….),java在java.util.Collections提供了一系列名字以unmodifiable为前缀的静态方法,可以创建指定Collection对象的一个副本,这个副本与原对象拥有相同的内容,但是只能读取,不可以修改,任何试图调用修改原对象内容的方法,都会抛出UnsupportedOperationException异常,这就有点像C++的const常量了。 以List为例:

    List<Integer> list=new ArrayList<Integer>();
    list.add(122);
    list.add(5);
    List<Integer> listReadOnly=java.util.Collections.unmodifiableList(list);
    for(Integer i:listReadOnly)
        System.out.println(i); // 可正常读取
    listReadOnly.add(100)// 抛出 UnsupportedOperationException异常

java本身提供了Collection<E>提供了创建readonly对象的方式,但是限制于java本身的机制,java并没有为普通的Object提供类似的普适的方法来创建readonly对象。

因为jface databinding本身的现实需求,jface 数据绑定技术中提供了对Observable对象的影子对象的创建方法。 比如,我们有时需要向外部提供一个Observable对象,以用于调用者观察这个对象的改变,但又不允许调用者修改对象,这时候,就不能把Observable对象直接提供给调用者,而是希望提供一个只读(readonly)的副本,或者叫影子对象,调用者可以通过这个影子对象感知真正的Observable对象的所有数据改变,但不能修改它,说白了—就是只许看不许摸。 下面是DataBindingContext的构造函数代码,就有这种影子对象的应用:

    public DataBindingContext(Realm validationRealm) {
        Assert.isNotNull(validationRealm, "Validation realm cannot be null"); //$NON-NLS-1$
        this.validationRealm = validationRealm;

        ObservableTracker.setIgnore(true);
        try {
            bindings = new WritableList(validationRealm);
            // 为bindings成员变量创建一个影子对象
            unmodifiableBindings = Observables
                    .unmodifiableObservableList(bindings);

            validationStatusProviders = new WritableList(validationRealm);
            // 为validationStatusProviders成员变量创建一个影子对象
            unmodifiableStatusProviders = Observables
                    .unmodifiableObservableList(validationStatusProviders);

            validationStatusMap = new ValidationStatusMap(validationRealm,
                    bindings);
        } finally {
            ObservableTracker.setIgnore(false);
        }
    }
    // getBindings实际返回的是替身unmodifiableBindings,而不是bindings真身
    public final IObservableList getBindings() {
        return unmodifiableBindings;
    }
    // getValidationStatusProviders实际返回的是替身unmodifiableStatusProviders,而不是validationStatusProviders真身
    public final IObservableList getValidationStatusProviders() {
        return unmodifiableStatusProviders;
    }

从下面的类型层次结构图中可以看到,对于Map,Set,List以及普通的ObservableValue对象,jface都有对应的影子对象

调用org.eclipse.core.databinding.observable.Observables中对应的静态方法,就可以为Observable对象创建对应的影子对象:

如下为一个String类型Observable对象name创建了对应的影子对象unmodifiableName

            WritableValue<String> name = new WritableValue<String>();
            IObservableValue<String> unmodifiableName = Observables.unmodifiableObservableValue(name);

如下为一个ObservableMap对象widgetBindings创建了对应的影子对象unmodifiableWidgetBindings

    WritableMap<String,Binding> widgetBindings=new WritableMap<String,Binding>();
    IObservableMap<String, Binding> unmodifiableWidgetBindings=Observables.unmodifiableObservableMap(widgetBindings);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Vamei实验室

Python深入06 Python的内存管理

语言的内存管理是语言设计的一个重要方面。它是决定语言性能的重要因素。无论是C语言的手工管理,还是Java的垃圾回收,都成为语言最重要的特征。这里以Python语...

1969
来自专栏Android机动车

设计模式——模板方法模式

● 1.定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。

641
来自专栏C/C++基础

设计模式 (5)——工厂方法模式(Factory Method,创建型)

使用设计模式可以提高代码的可复用性、可扩充性和可维护性。工厂方法模式(Factory Method Pattern)属于创建型模式,定义一个创建对象的接口函数,...

521
来自专栏C/C++基础

C++智能指针

C++中,动态内存的管理是通过一对运算符来完成的,new用于申请内存空间,调用对象构造函数初始化对象并返回指向该对象的指针。delete接收一个动态对象的指针,...

731
来自专栏前端知识分享

第195天:js---函数对象详解(call、apply)

753
来自专栏积累沉淀

Java设计模式(十四)----模板方法模式

模板方法模式 一、概述 二、结构 三、具体案例 四、优缺点和设计思想 一、概述 模板方法模式是类的行为模...

1895
来自专栏JetpropelledSnake

Python入门之装饰器

讲 Python 装饰器前,我想先举个例子,虽有点污,但跟装饰器这个话题很贴切。 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我...

27012
来自专栏magicsoar

Effective Modern C++翻译(7)-条款6:当auto推导出意外的类型时,使用显式的类型初始化语义

条款6:当auto推导出意外的类型时,使用显式的类型初始化语义 条款5解释了使用auto来声明变量比使用精确的类型声明多了了很多的技术优势,但有的时候,当你想要...

17210
来自专栏老九学堂

【超全】C语言初学者必须掌握的关键字!

其实小伙伴在写代码的时候,关键字还是用的比较多的,老九主要就平常中用到的常用关键字进行总结,便于小伙伴们更全面的理解其在代码中的意图。 C语言关键字总结 sta...

3366
来自专栏阿杜的世界

【转】Java知识点集锦(1~40)

答:不是。Java中的基本数据类型只有8个:byte、short、int、long、float、double、char、boolean;除了基本类型(primi...

692

扫码关注云+社区