首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于JSON / Web的WorkGroup数据服务

基于JSON / Web的WorkGroup数据服务
EN

Code Review用户
提问于 2014-12-03 12:35:34
回答 3查看 1.4K关注 0票数 3

我想知道这段代码是否可以变得更清晰、更流畅:

代码语言:javascript
复制
using System;
using System.Threading.Tasks;
using Windows.Data.Json;
using System.Collections.ObjectModel;
using System.Net.Http;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Linq;
using eTest.Space.Log;
using eTest.Space.Interface;
using eTest.Objects;

namespace eTest.Space.Services
{

    public class WorkGroupDataService : IWorkgroupDataService
    {


        public string WebApiUri
        {
            get { return Constants.ServerAddress; }
        }

        private ObservableCollection<IWorkgroup> Groups;// = new ObservableCollection<IWorkgroup>();

        public async Task<ObservableCollection<IWorkgroup>> GetAllWorkGroups()
        {
            Groups = new ObservableCollection<IWorkgroup>();
            //if (Groups.Count == 0)
            {
                Uri dataUri = new Uri(WebApiUri + "api/workgroup/");

                using (var client = new Windows.Web.Http.HttpClient())
                {
                    var response = await client.GetAsync(dataUri).AsTask(); ;

                    string jsonText = response.Content.ReadAsStringAsync().GetResults();
                    JsonArray jsonArray = JsonArray.Parse(jsonText);

                    foreach (JsonValue groupValue in jsonArray)
                    {
                        JsonObject groupObject = groupValue.GetObject();
                        IWorkgroup group = new Workgroup();
                        group.GroupState = (int)groupObject["GroupState"].GetNumber();
                        group.WorkgroupName = groupObject["WorkgroupName"].GetString();
                        group.WorkgroupSecretary = groupObject["WorkgroupProba"].GetString();
                        group.ObjectID = groupObject["ObjectID"].GetString();
                        Uri dataUri1 = new Uri(WebApiUri + "api/etest/" + group.ObjectID);
                        using (var client1 = new Windows.Web.Http.HttpClient())
                        {
                            var response1 = await client.GetAsync(dataUri1).AsTask();
                            if (response1.StatusCode == Windows.Web.Http.HttpStatusCode.Ok)
                            {
                                string jsonText1 = response1.Content.ReadAsStringAsync().GetResults();
                                List<TestSession> Test = JsonConvert.DeserializeObject<List<TestSession>>(jsonText1);
                                group.Test = Test;
                            }
                        }
                        if (group.Test.Count > 0)
                        {
                            Groups.Add(group);
                        }

                    }
                }
            }
            Groups = new ObservableCollection<IWorkgroup>(Groups.OrderByDescending((x => x.Test.Count)));
            return Groups;
        }
    }
}
EN

回答 3

Code Review用户

回答已采纳

发布于 2014-12-03 13:42:20

命名约定

私有实例字段应该是小写:

代码语言:javascript
复制
private ObservableCollection<IWorkgroup> groups;

局部变量也应是小写:

代码语言:javascript
复制
List<TestSession> test = JsonConvert.DeserializeObject<List<TestSession>>(jsonText1);

另外,在对客户端和URI执行相同的操作时,您要将数字添加到第二个变量中,例如client1。试着想一些更具描述性的东西,这两个客户端服务于两个不同的目的,所以尝试类似于purposeClient这样的东西,其中的目的被一个词替换为它的目的。此时,将功能提取到单独的方法中可能是个好主意。

改进

如果要使用async方法,则应该使用await方法:

代码语言:javascript
复制
var jsonText = await response.Content.ReadAsStringAsync().GetResults();

结构

类似地,考虑到这个变量看起来不需要在方法之间共享(除非您还没有包含类的其他部分),我不太清楚为什么要将它变成实例字段,并且可以在GetAllWorkGroups()方法中轻松地声明它。

在该方法中,您似乎为Groups分配了两次值,不需要执行第二个方法:

代码语言:javascript
复制
groups = groups.OrderByDescending(x => x.Test.Count);

您似乎还将OrderByDescending子句双包装在括号中,这是不必要的。

您似乎在使用varstring之间进行切换。很多人确实会切换,在推断类型明显的情况下使用var,当不是立即使其更加可读性时使用该类型(这就是我所做的),但很多人将只使用var。就风格而言,我肯定会采取这样或那样的方式,因为目前你的切换看起来很混乱。

我发现对象初始化器使代码更具可读性,因此在这里:

IWorkgroup组=新工作组();group.GroupState = (int)groupObject“GroupState”.GetNumber();group.WorkgroupName = groupObject“WorkgroupName”.GetString();group.WorkgroupSecretary = groupObject“WorkgroupProba”.GetString();group.ObjectID = groupObject“ObjectID”.GetString();

可以是:

代码语言:javascript
复制
IWorkgroup group = new Workgroup 
{
    GroupState = (int)groupObject["GroupState"].GetNumber(),
    WorkgroupName = groupObject["WorkgroupName"].GetString(),
    WorkgroupSecretary = groupObject["WorkgroupProba"].GetString(),
    ObjectID = groupObject["ObjectID"].GetString()
};

在此之后,您将启动一个新的using,但是从代码中可以看出,您实际上已经使用了以前的客户端,因此您可以将它移动到如下所示:

代码语言:javascript
复制
public async Task<ObservableCollection<IWorkgroup>> GetAllWorkGroups()
{
    var groups = new ObservableCollection<IWorkgroup>();
    JsonArray jsonArray;

    using (var client = new Windows.Web.Http.HttpClient())
    {
        var dataUri = new Uri(WebApiUri + "api/workgroup/");
        var response = await client.GetAsync(dataUri).AsTask();

        var jsonText = await response.Content.ReadAsStringAsync().GetResults();
        jsonArray = JsonArray.Parse(jsonText);
    }

    foreach (var groupValue in jsonArray)
    {
        var groupObject = groupValue.GetObject();
        IWorkgroup group = new Workgroup
        {
            GroupState = (int)groupObject["GroupState"].GetNumber(),
            WorkgroupName = groupObject["WorkgroupName"].GetString(),
            WorkgroupSecretary = groupObject["WorkgroupProba"].GetString(),
            ObjectID = groupObject["ObjectID"].GetString()
        };

        var dataUri = new Uri(WebApiUri + "api/etest/" + group.ObjectID);
        using (var client = new Windows.Web.Http.HttpClient())
        {
            var response = await client.GetAsync(dataUri).AsTask();
            if (response.StatusCode == Windows.Web.Http.HttpStatusCode.Ok)
            {
                var jsonText = await response.Content.ReadAsStringAsync().GetResults();
                var test = JsonConvert.DeserializeObject<List<TestSession>>(jsonText);
                group.Test = test;
            }
        }

        if (group.Test.Count > 0)
        {
            groups.Add(group);
        }
    }

    return groups.OrderByDescending(x => x.Test.Count);
}
票数 7
EN

Code Review用户

发布于 2014-12-03 14:09:20

基于丹鲁尔's的好回答

如果是group.Test.Count == 0,将跳过IWorkgroup group完成的所有工作。所以你最好改变执行流程。

代码语言:javascript
复制
foreach (var groupValue in jsonArray)
{
    var groupObject = groupValue.GetObject();
    String objectId = groupObject["ObjectID"].GetString();

    var test = GetTestSessions(objectId);
    if (test.Count == 0) { continue; }

    IWorkgroup group = new Workgroup
    {
        GroupState = (int)groupObject["GroupState"].GetNumber(),
        WorkgroupName = groupObject["WorkgroupName"].GetString(),
        WorkgroupSecretary = groupObject["WorkgroupProba"].GetString(),
        ObjectID = objectId,
        Test = test
    };

    groups.Add(group);
}

调用提取的重载方法

代码语言:javascript
复制
private List<TestSession> GetTestSessions(String objectId)
{
    return GetTestSessions(new Uri(WebApiUri + "api/workgroup/" + objectId));
}

private List<TestSession> GetTestSessions(Uri dataUri)
{
    using (var client = new Windows.Web.Http.HttpClient())
    {
        var response = await client.GetAsync(dataUri).AsTask();
        if (response.StatusCode == Windows.Web.Http.HttpStatusCode.Ok)
        {
            var jsonText = await response.Content.ReadAsStringAsync().GetResults();
            return JsonConvert.DeserializeObject<List<TestSession>>(jsonText);
        }

        return new List<TestSession>();
    }

}
票数 3
EN

Code Review用户

发布于 2014-12-03 13:33:43

绝对一点儿没错!在C#中有很多很酷的捷径。我将把它们应用到代码中,并对它们进行注释:

代码语言:javascript
复制
namespace eTest.Space.Services
{
    public class WorkGroupDataService : IWorkgroupDataService
    {
        public string WebApiUri
        {
            get { return Constants.ServerAddress; }
        }

        public async Task<ObservableCollection<IWorkgroup>> GetAllWorkGroups()
        {
            // WARNING: You have a private member that has the potential to be 
            // shared across threads if GetAllWorkGroups is used asynchronously!
            // Swapped for a local variable instead.
            var groups = new ObservableCollection<IWorkgroup>();
            //if (groups.Count == 0)
            {
                // Love the var keyword, means typing the Type once instead of twice
                var dataUri = new Uri(WebApiUri + "api/workgroup/");

                string jsonText;
                using (var client = new Windows.Web.Http.HttpClient())
                {
                    // AsTask redundant, already a task
                    // ConfigureAwait to avoid unnecessary context switch (you'll await again outside this and can choose to keep context or not depending on if you do work in the UI
                    var response = await client.GetAsync(dataUri).ConfigureAwait(false);

                    // we're using async, await when getting results to trigger thread release while waiting
                    jsonText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                // We close the using as early as possible to release the object as early as possible
// Also, the less nesting of scopes, the easier your code is to read
                }

                foreach (var groupValue in jsonArray)
                {
                    var groupObject = groupValue.GetObject();

                    // Moved body of foreach to its own method
                    var group = GetGroupFromGroupObject(groupObject);

                    if (group.Test.Count > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            // Removed the private member assign, returned the local variable
            return groups;
        }

        private Group GetGroupFromGroupObject(GroupObject groupObject)
        {
            // Object initializer for cleaner syntax
            var group = new Workgroup
            {
                GroupState = (int)groupObject["GroupState"].GetNumber();
                WorkgroupName = groupObject["WorkgroupName"].GetString();
                WorkgroupSecretary = groupObject["WorkgroupProba"].GetString();
                ObjectID = groupObject["ObjectID"].GetString();
            }

            // string.format reads better
            // dropping args to their own lines can improve readability
            var uriString = string.Format(
                                "{0}api/etest/{1}", 
                                WebApiUri, 
                                group.ObjectID);

            // Avoiding nested calls can make for easier reading
            var dataUri1 = new Uri(uriString);

            using (var client1 = new Windows.Web.Http.HttpClient())
            {
                var response1 = await client.GetAsync(dataUri1).ConfigureAwait(false);
                if (response1.StatusCode == Windows.Web.Http.HttpStatusCode.Ok)
                {
                    var jsonText1 = await response1.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // No need to create a separate var just to assign
                    // Type T will be inferred from the object, no need to write it
                    group.Test = JsonConvert.DeserializeObject(jsonText1);
                }
            }

            return group;
        }
    }
}
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/71500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档