封装集合:编程中的单数与集合

单个实例与集合,类似于英文中单数与复数的,例如 photo 和 photos,student 和 students。

如果直接在业务类中使用集合去定义复数,则该集合只承载了容器功能,所有涉及到集合的操作,不可避免地写进了业务类,使得业务类臃肿。另外,由于集合是开放的,数据可在业务类中修改,使得数据被修改不可控。

我们不妨更进一步,从概念上将其抽象为照片与相册,学生与班级等等,不仅具备容器功能,还具备管理集合的功能。一种合乎逻辑的访问方式不仅有助于思考,同时会使得代码简洁易读。

这种编程方式很常见,只是最近在使用中感觉其对手头上的一个项目越发重要。故而整理一个小例子记录之。

以照片和相册为例:

class Photo
{
    public Photo(string name, string path)
    {
        Name = name;
        Path = path;
    }
    public string Name;
    public string Path;
    public string Note;
}

class Album
{
    public Album(string name, string subject)
    {
        Name = name;
        Subject = subject;
        Photos = new Dictionary<string, Photo>();
    }
    public string Name;
    public string Subject;
    private Dictionary<string, Photo> Photos;
    public Photo this[string photoname]
    {
        get
        {
            if (Photos.ContainsKey(photoname))
            {
                return Photos[photoname];
            }
            else
            {
                return null;
            }
        }
        set
        {
            if (Photos.ContainsKey(photoname))
            {
                throw new ArgumentException("重复的主键");
            }
            else
            {
                Photos.Add(photoname, value);
            }
        }
    }
}

static void Main(string[] args)
{
  // Album a
= new Album("风景", "高山"); var p1 = new Photo("泰山", @"D: aishan.jpg"); var p2 = new Photo("黄山", @"D:huangshan.jpg"); a[p1.Name] = p1; a[p2.Name] = p2;   // var p = a["黄山"]; }

避免将 Photos 这种集合定义在业务类中,因为这往往涉及到集合的操作,而集合的操作可能需要各种附加信息。通过定义 Album 类,可适当添加一些属性和方法,用于管理集合。这种方式可使得业务逻辑类单纯。

扩展:该方法基本上可以看做是《重构》中的“封装集合”。

原文地址:https://www.cnblogs.com/ShengunErshu/p/12670229.html