马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

重构之将值对象改为引用对象(Change Value to Reference)

[复制链接]
查看3611 | 回复2 | 2019-3-25 23:38:19 | 显示全部楼层 |阅读模式
       在C#中,我们经常说类型分为两种,值类型跟引用类型;同样的,我们也可对对象做这样的分类:引用对象和值对象。前者如“客户”、“帐户”等,每个对象都代表现实中的一个实物,我们可以直接拿来对比两个对象是否相等。后者如“日期”、“时间”、“钱”、等,这些完全是用数据值来定义,并不会在意副本的存在,一个系统中可以有成千上万的“日期”对象。       有时,我们要用一个类去存储一些不可修改的数据(这时它是一个值对象),但随着系统的壮大,我们会对这个类加入一些可修改数据,并确保对任何一个对象的修改都能影响到所有引用这对象的地方。这时候我们就需要对这个类进行“将值对象改为引用对象(Change Value to Reference)”重构,把值对象收为引用对象。
       不知道大家还记不记得上一章写的“[url=重构之以对象取代数据值(Replace Data Value With Object) http://www.ibcibc.com/forum.php? ... 20&fromuid=9905 (出处: IBC编程社区-C#论坛-C#教程,ASP.NET教程-C#源码)]以对象取代数据值(Replace Data Value With Object)[/url]”,这一次我们从上一章重构后的代码为例子;
Customer类
[C#] 纯文本查看 复制代码
public class Customer
{
    private string _name;
    /// <summary>
    /// 名称
    /// </summary>
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
 
    private string _jName;
    /// <summary>
    /// 简称
    /// </summary>
    public string JName
    {
        get { return _jName; }
        set { _jName = value; }
    }
 
    private string _address;
    /// <summary>
    /// 地址
    /// </summary>
    public string Address
    {
        get { return _address; }
        set { _address = value; }
    }
 
}

Order 类
[C#] 纯文本查看 复制代码
class Order
{
private string _customer;
 
public string Customers
{
get { return _customer; }
set { _customer = value; }
}

public Order(string customer)
{
 CustomerClass =  new Customer();
CustomerClass.Name = customer;
}
        public Order(string customer,string jname)
        {
            CustomerClass = new Customer();
            CustomerClass.Name = customer;
            CustomerClass.JName = jname;
        }
 
        public Order(Customer Customer)
        {
            CustomerClass = Customer;
        }
}

目前上面的代码都还是每一个Order类对象拥有各自的Customer类对象。但现在我希望改变这一情况,希望一个Customer类可以被多个Order类使用(一个客户拥有多个不同的订单)。这就意味着我一个客户名称只有一个对象。所以首先我们要先提供一个统一入口,然后把构造函数改为私有函数:
[C#] 纯文本查看 复制代码
        private Customer(string name)
        {
            Name = name;
        }

        public static Customer create(string name)
        {
return new Customer(name);
        }

我们有了统一的入口,但”客户“是会有多个的,所以我们要用一个集合数组(List、Dictionary等)来存储所有Customer 对象。
[C#] 纯文本查看 复制代码
 private static Dictionary<string, Customer> _instancer;

        private void store()
        {
             _instancer.Add(this.Name,this);
        }

因为我们把对象都存到了_instancer里面,所以入口create函数就要改成
[C#] 纯文本查看 复制代码
        public static Customer create(string name)
        {
            return getNamed(name);
        }

        public static Customer getNamed(string name)
        {
            return (Customer)_instancer.FirstOrDefault(a=>a.Key==name).Value;
        }


最后我们在决定应该在接到请求时创建新的Customer 对象呢,还是先预先创建。这个要看自己的业务需要,做出相应的调整;这里我们先用预先创建做例子。
[C#] 纯文本查看 复制代码
public static void loadCustomers()
        {
            new Customer("Lemon Car Hire").store();
            new Customer("Associated Coffee Machines").store();
            new Customer("Bilston Gasworks").store();
        }




参考文献
重构——改善既有代码的设计   【美】Martin Fowler 著
                                                                         熊节 译





*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则