代码之家  ›  专栏  ›  技术社区  ›  letmaik

如何限制对可变或不可变方法的访问?

  •  2
  • letmaik  · 技术社区  · 16 年前

    主要的问题是,我想在某些情况下隐藏类的可变部分,这样MVC的视图层就不能直接修改对象,而必须通过它的控制器。

    我想到了两种方法:

    1. 创建一个包含所有不可变方法(只读)的接口“Thing”,并创建一个包含setters的接口“MutableThing”。

    2. 将所有方法放在一个接口中,并通过像集合.不可修改列表(obj)方法,以便在访问变异方法时抛出异常。

    我更喜欢第一个,因为我认为它更干净,设计得更好,但我有一个问题。我在“Thing”接口中有addListener(l)和removeListener(l),因此视图层可以将自己注册为一些模型对象的侦听器。但是在“Thing”接口中使用这两种方法,它本身就没有意义了。如果没有方法实际更改数据,为什么接口能够注册信号数据更改的侦听器?我可以将这些方法放在“MutableThing”接口中,但视图层只能访问“Thing”接口,不能将自己注册为侦听器。

    这之所以不起作用,仅仅是因为侦听器,视图层是否真正负责将自己注册为模型上的侦听器?如果控制器能够以某种方式做到这一点(它可以访问“可变对象”),那么就不会有问题,但我不知道如何实现它。

    谢谢!

    4 回复  |  直到 16 年前
        1
  •  3
  •   Michael Lloyd Lee mlk    16 年前

    如果没有方法实际更改数据,为什么接口能够注册信号数据更改的侦听器?

        2
  •  1
  •   gia    16 年前

    我会第一次尝试修改一下。

    您可以通过一个包含所有getter的接口来定义不可变的。可变类实现不可变接口,并包含所有必需的set方法,而不需要接口指定这些方法。在代码中,只能通过不可变接口访问实例。

    此外,创建(并修改)实例后,可以使用seal()方法来密封实例。无论何时调用set方法,都要检查实例是否未密封。这可能有助于防止修改(或者在大团队中工作时)。

        3
  •  1
  •   supercat    15 年前

    正确的方法通常是有三个类和/或接口:ReadableFoo、ImmutableFoo和MutableFoo。后两个独立于第一个,这意味着当需要ReadableFoo时可以使用其中一个,但是当需要ImmutableFoo时只能使用ImmutableFoo,同样地,对于MutableFoo也是如此。ReadableFoo包含CloneAsMutable、AsMutable和AsImmutable的方法可能会有所帮助。CloneAsMutable将始终使用从原始对象复制的属性创建新的可变对象。在ReadableFoo上调用AsMutable和AsImmutable将返回原始对象(如果它是所需的类型)或包含从原始对象复制的数据的新对象(如果它不是)。

        4
  •  0
  •   Jesper    16 年前

    在我看来,你提到的两种可能性都是解决问题的有效方法。关于第一种方法:我假设你指的是接口 MutableThing 扩展接口 Thing 添加mutator方法。

    事情 易变的 java.util.Observable 类和 java.util.Observer