none
【单例模式】关于 WP8/8.1 项目模板的 SampleDataSource.cs 文件的一些疑问! RRS feed

  • 问题

  • 下图是 WP8/8.1 项目模板的 SampleDataSource.cs 文件的一部分。

    • 从 ① 可以看出这个类应该采用了单例模式,但它却没有屏蔽构造函数,这是为什么?
    • 我标记了多个 ② 处,这里为什么用 _sampleDataSource.xxx 的方式引用成员,这与直接引用 xxx 有什么区别?这与 SampleDataSource.xxx 的引用方式又有什么区别?这 3 者之间又有什么区别?(问题有点多啊==)
    • 标记 ③ 处,为什么又改用 this.xxx 的方式引用成员了呢?为什么不用 _sampleDataSource.xxx
    /// <summary>
    /// 创建包含从静态 json 文件读取内容的组和项的集合。
    /// 
    /// SampleDataSource 通过从项目中包括的静态 json 文件读取的数据进行
    /// 初始化。 这样在设计时和运行时均可提供示例数据。
    /// </summary>
    public sealed class SampleDataSource
    {
        ①private static SampleDataSource _sampleDataSource = new SampleDataSource();
    
        private ObservableCollection<SampleDataGroup> _groups = new ObservableCollection<SampleDataGroup>();
        public ObservableCollection<SampleDataGroup> Groups
        {
            get { return this._groups; }
        }
    
        public static async Task<IEnumerable<SampleDataGroup>> GetGroupsAsync()
        {
            await ②_sampleDataSource.GetSampleDataAsync();
    
            return ②_sampleDataSource.Groups;
        }
    
        public static async Task<SampleDataGroup> GetGroupAsync(string uniqueId)
        {
            await ②_sampleDataSource.GetSampleDataAsync();
            // 对于小型数据集可接受简单线性搜索
            var matches = ②_sampleDataSource.Groups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }
    
        public static async Task<SampleDataItem> GetItemAsync(string uniqueId)
        {
            await ②_sampleDataSource.GetSampleDataAsync();
            // 对于小型数据集可接受简单线性搜索
            var matches = ②_sampleDataSource.Groups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }
    
        private async Task GetSampleDataAsync()
        {
            if (③this._groups.Count != 0)
                return;
    
            Uri dataUri = new Uri("ms-appx:///DataModel/SampleData.json");
    
            StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
            string jsonText = await FileIO.ReadTextAsync(file);
            JsonObject jsonObject = JsonObject.Parse(jsonText);
            JsonArray jsonArray = jsonObject["Groups"].GetArray();
    
            foreach (JsonValue groupValue in jsonArray)
            {
                JsonObject groupObject = groupValue.GetObject();
                SampleDataGroup group = new SampleDataGroup(groupObject["UniqueId"].GetString(),
                                                            groupObject["Title"].GetString(),
                                                            groupObject["Subtitle"].GetString(),
                                                            groupObject["ImagePath"].GetString(),
                                                            groupObject["Description"].GetString());
    
                foreach (JsonValue itemValue in groupObject["Items"].GetArray())
                {
                    JsonObject itemObject = itemValue.GetObject();
                    group.Items.Add(new SampleDataItem(itemObject["UniqueId"].GetString(),
                                                       itemObject["Title"].GetString(),
                                                       itemObject["Subtitle"].GetString(),
                                                       itemObject["ImagePath"].GetString(),
                                                       itemObject["Description"].GetString(),
                                                       itemObject["Content"].GetString()));
                }
                ③this.Groups.Add(group);
            }
        }
    }

    2015年9月26日 2:24

答案

  • 你好,

    问题1: 屏蔽构造函数应该是指不公开构造函数。这样类外部就不能实例化这个对象,必须要让类的方法返回该类的实例,这样我们才好控制并保证系统中只有一个该类的实例。另一方面,构造函数是没法屏蔽的,如果类中你不写,系统会自动为该类添加一个默认的构造函数。你这个例子就是这种情况,系统为SampleDataSource添加了无参数默认构造函数。

    问题2:

    _sampleDataSource.xxx 这个是指调用对象的方法;直接引用 xxx 是在类的定义中找到xxx方法并调用;SampleDataSource.xxx这个是调用该类的静态方法。_sampleDataSource在这个例子里面是sampledatasource 类的对象,你也可以实例化其他类的对象,跟第二个xxx方法没有什么关系。只是这个例子比较特殊,申明了一个相同类的实例。最后一个是静态方法,只是借用了类的名称来调用静态方法。

    问题3:

    this.method是指当前类的实例里面的方法,你可以认为this就是实例化当前类构造函数得到的对象;_sampleDataSource.xxx是指特定对象的方法,可以是其他任何类型的方法。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年9月28日 2:56