zoukankan      html  css  js  c++  java
  • 理解值与引用[学习]

     

    面向对象分析和设计需要区分对象的值语义与引用语义。 

    我的一块钱和你的一块钱相等,这是

    20岁的我和30岁的我是同一个人,这是语义

     

    值对象包括2大特征:表示和运算。比如:3这个整数在计算机内部用二进制11表示,可以参与+,-,*,/等运算;

    引用对象包括3大特征:标识、状态 和 行为。比如:person对象拥有不变的标识,并可通过行为改变状态。

     

    值对象的同一性建立在表示的基础上,而引用对象的同一性建立在标识的基础上。

    值对象只能被动地参与运算,引用对象拥有主动的行为。

     

    struct 和 class 是 OOP 语言为分别表达值语义和引用语义所提供的语法机制。 

    C#中 struct 可以实现接口,可以定义方法;但从语义角度,对于 struct 类型的 DateTime 对象 today,today.AddDays(1) 的语义是today 和 1 参与 AddDays 运算得出一个新的日期值。

     

    由于值对象的同一性建立在表示的基础上,而引用对象的同一性建立在标识的基础上。值对象从语义上是不可变的,而引用对象从语义上是不可拷贝的。但在 实际实现中由于性能考虑常常会用引用语法来实现值语义,比如:C# 的 string 是值语义,但却是引用语法;类似的,flyweight 模式被共享的小对 象也是引用语法表达值语义。由于值语义的不可变性要求,用引用语法模拟值语义常常会加上不可变的限制,比如:C# 的 string 对象在参与 + 运算本身并不 改变,而是产生一个新 string 对象作为结果。这种通过不可变引用语法来模拟值语义的手段在不支持 struct 的 Java 中更加常用。而在 C++ 中,虽 然提供了 struct 和class,但二者在语法上都是值语法(可拷贝);所以,在 C++ 中常常会为 class 加上不可拷贝的限制明确引用语义,强制使用指针或引用的方式使用对象。 

     

    在使用上,值对象通常用于表示引用对象的某一属性,比如:颜色RGB,字体类型,出生日期。

    下面通过一个例子进一步体会值与引用的区别:

    class Person{
        
    private DateTime m_birthday;
        
    public DateTime GetBirthday(){
             
    return m_birthday;
        }
    }

    值类型的 m_birthday 对象是为了描述引用类型 Person 某一方面属性的。

    如果 DateTime 是 class,那么 GetBirthday 只需要返回引用;

    如果 DateTime 是 struct,那么 GetBirthday 就是值拷贝。

     

    从性能角度,返回引用优于值拷贝;但从设计角度,返回引用使得外部可以直接修改 Person 对象的内部状态,破坏了封装。

    如果是 Java,由于不支持 struct,所以只能在引用语法的基础上模拟值语义,比如:返回一份 clone。

    显然,由于 C# 对 struct 的直接支持,一旦明确了 m_birthday 的值语义,那么语法的支持直接而简洁。

     

    确定领域对象是值语义还是引用语义是分析设计阶段的事情,其原则是基于值对象和引用对象的特征。

    而对于 struct 和 class 的选择是实现阶段的事情。

     

    假如分析设计确定领域对象是引用语义,那么语法选择只有 class,不可能去选择 struct ;

    而如果领域对象是值语义,比如 dateTime 或 string,那么语法选择可以是 struct 也可以是 class。struct 是默认的选择,即使由于性能原因选择了class,还是需要像 string 一样注意设计细节去表达值语义。我们提倡的是在明确领域对象的语义后,应该首选默认选项,即用struct 表示值,用 class 表示引用。默认不需要理由,不用默认才需要理由。

     

    参考:

    《冒号课堂--编程范式与OOP思想》

    《Effective C#》

    《领域驱动设计精简版》

     

    来源:http://www.cnblogs.com/weidagang2046/archive/2010/07/24/1784340.html

    作者: XuGang   网名:钢钢
    出处: http://xugang.cnblogs.com
    声明: 本文版权归作者和博客园共有。转载时必须保留此段声明,且在文章页面明显位置给出原文连接地址!
  • 相关阅读:
    cinder支持nfs快照
    浏览器输入URL到返回页面的全过程
    按需制作最小的本地yum源
    创建可执行bin安装文件
    RPCVersionCapError: Requested message version, 4.17 is incompatible. It needs to be equal in major version and less than or equal in minor version as the specified version cap 4.11.
    惠普IPMI登陆不上
    Linux进程状态——top,ps中看到进程状态D,S,Z的含义
    openstack-neutron基本的网络类型以及分析
    openstack octavia的实现与分析(二)原理,架构与基本流程
    flask上下文流程图
  • 原文地址:https://www.cnblogs.com/xugang/p/1787580.html
Copyright © 2011-2022 走看看