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
    声明: 本文版权归作者和博客园共有。转载时必须保留此段声明,且在文章页面明显位置给出原文连接地址!
  • 相关阅读:
    struts2增删改查---layer---iframe层---通配符---国际化
    struts2增删改查---layer---iframe层
    struts2相关简单介绍
    直接在数据库客户端插入当前时间
    STL find() ,还是挺重要的
    两种应该掌握的排序方法--------1.shell Sort
    程序员的工具箱
    计算机科学中最重要的32个算法
    函数的重载与 泛型(generic)有什么不同?
    ruby编程语言-学习笔记5(第5章 语句和控制结构)
  • 原文地址:https://www.cnblogs.com/xugang/p/1787580.html
Copyright © 2011-2022 走看看