埃菲尔铁塔的一成不变 [英] Immutable class in Eiffel

查看:86
本文介绍了埃菲尔铁塔的一成不变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Eiffel中创建一个不变的POINT类.下面的代码定义一个吗? xy字段的{NONE}可访问性就足够了吗?我可以给类不变式写一些东西,如x = x',还是可以实现不变性?

I'm trying to make an immutable POINT class in Eiffel. Is the code below defines one? The {NONE} accessibility for the x and y fields is enough for it? Can I write something to the class invariant like x = x', or how else can I achieve immutability?

class POINT
    create
        make
    feature {NONE}
        x: DOUBLE
        y: DOUBLE
    feature
        make (x_: DOUBLE; y_: DOUBLE)
        do
            x := x_
            y := y_
        ensure
            set: x = x_ and y = y_
        end

    feature --accessors
        get_x: DOUBLE
        do
            Result := x
        ensure
            Result = x
        end
    end

推荐答案

Eiffel不允许其客户端更改类的属性.例如,以下代码被拒绝:

Eiffel does not allow to change attributes of a class by its clients. For example, the following code is rejected:

p: POINT
...
p.x := 5.0

因此,不需要提供吸气剂(就像某些其他语言一样).只要将x充分导出到客户端类,就可以使用p.x.因此,您的示例代码可以简化为

As a result, there is no need to provide getters (like in some other languages). You can just use p.x provided that x is sufficiently exported to a client class. So, the code of your example can be simplified to

class POINT
create
   make
feature -- Access
   x: DOUBLE
   y: DOUBLE
feature {NONE} -- Creation
   make (x0: DOUBLE; y0: DOUBLE)
      -- Initialize object with `x0' and `y0'.
   do
      x := x0
      y := y0
   ensure
      set: x = x0 and y = y0
   end
end

请注意,创建过程不再不再导出,否则可以将其用作常规(即非创建)例程并更改属性,也就是说我们可以做如下的事情

Note that the creation procedure is not exported anymore, otherwise it would be possible to use it as a normal (i.e. non-creation) routine and to change the attributes, that is we would be able to do something as follows

create p.make (1, 1)
p.make (2, 3)
print (p)

,这将显示(2, 3),即您可以更改原始对象p的值,使其可变.

and this would print (2, 3), i.e. you would be able to change the value of the original object p, making it mutable.

尽管现在不能直接更改属性,但仍然可以在类型为POINT的对象上调用功能copy并更改整个对象.如果还想避免这种情况,则可以在类POINT中重新定义功能以引发异常,甚至具有后置条件False都会导致运行时为您引发异常:

Though, now the attributes cannot be changed directly, it's still possible to call feature copy on an object of type POINT and to change the whole object. If you want to avoid this situation as well, the feature can be redefined in the class POINT to raise an exception, or even to have a postcondition False causing the run-time to raise an exception for you:

copy (other: like Current)
      -- <Precursor>
   do
      (create {EXCEPTIONS}).raise ("Attempt to change an immutable object.")
   ensure then
      is_allowed: False
   end

这篇关于埃菲尔铁塔的一成不变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆