寻找有关我的服务器设计的一般反馈,尤其是关于使用通用方法

时间:2011-02-02 17:35:17

标签: c# design-patterns generics

此问题是我之前发布的帖子here的后续问题。 Martinho要求我提供有关我的系统的更多信息。他建议可能有更好的方法来实现我的目标。所以,如果这里有问题,我想我想知道这是不是很糟糕的设计?如果是这样,可以改进什么以及如何(我从插图中学到最多)。感谢。

我正在为工作中的iPhone应用程序设计中间件。

开发人员不想从客户端显式调用各种对象,而是希望使用泛型,其中“Group”基于传入的参数返回JSON字符串。该参数表示用户登录时看到的第一个屏幕。我们将登录屏幕称为“仪表板”。

因此,当客户端调用服务器方法时:

 Contracts.GroupDto IDashboardService.GetGroupById(string groupId)
        {
            var obj = GroupRepository.GetGroupById(groupId);

            return new Contracts.GroupDto
            {
                ...
            };
        }

服务器使用GroupRepository方法GetGroupById返回通用对象类型:

public static IList<G> GetGroupById<G>(int groupId)
        {

            DashboardGroupType type = (DashboardGroupType)groupId;
            IList<G> result = new List<G>();

            var obj = default(G);

            switch (type)
            {
                case DashboardGroupType.Countries:
                    break;
                case DashboardGroupType.Customers:
                    // this returns a list of typ  IEnumerable<Customer>
                    obj = (G) CustomerRepository.GetAllCustomers();
                    break;
                case DashboardGroupType.Facilities:
                    // this returns a list of typ  IEnumerable<Facility>
                    obj = (G) FacilityRepository.GetAllFacilities();
                    break;
                case DashboardGroupType.Heiarchy:
                    break;
                case DashboardGroupType.Lines:
                    break;
                case DashboardGroupType.Regions:
                    // this returns a list of typ  IEnumerable<string>
                    obj = (G) CustomerRepository.GetRegionsHavingCustomers();
                    break;
                case DashboardGroupType.States:
                    // // this returns a list of typ  IEnumerable<Customer>
                    obj = (G) CustomerRepository.GetStatesHavingCustomers();
                    break;
                case DashboardGroupType.Tanks:
                    break;
                default:
                    break;
            }

            result.Add(obj);


            return result;

        }

返回的对象类型基于传入GetGroupById的参数。例如,如果值为1,则该方法将查看DashboardGroupType枚举:

并传递参数1,服务器查看以下枚举:

 public enum DashboardGroupType
    {
        Countries = 0,
        Regions = 1,
        Customers = 2,
        Facilities = 3,
        Lines = 4,
        Tanks = 5,
        States = 6,
        Heiarchy = 7
    }

并将一个IEnumerable类型的区域列表返回给调用客户端。

有关此设计的任何想法(特别是关于IList GetGroupById(int groupId)方法?如果您有任何建议,我将非常感谢您的改进。

提前致谢。

2 个答案:

答案 0 :(得分:1)

这段代码对我来说没什么意义。您的通用返回IList<G>,但该列表只添加了一个项目。有时该项目为null(或default<G>,当null为参考类型时,该项为G

我无法想象为什么开发人员支持GetGroupById泛型方法,这样做比使用单独的方法更复杂。也就是说,为什么没有GetFacilitiesGetCustomers等?

也许他们更喜欢使用单一服务方法将JSON返回给他们。如果有一些令人信服的理由这样做(虽然我无法想象一个,除了开发人员的懒惰),那么我建议你在那个方法中做switch而不是乱用泛型。那就是:

Contracts.GroupDto IDashboardService.GetGroupById(string groupId)
{
    switch ((DashboardGroupType)groupId)
    {
        case DashboardGroupType.Regions:
            // Get the Regions list, convert to JSON, and return.
            break;
        // do the same kind of thing for the other group types.
    }
}

在这种情况下添加泛型方法只是不必要的复杂性 - 它不会简化或增加对代码的理解。相反,它使代码更难理解。

一般情况下,如果你的泛型方法中的代码根据类型参数采取不同的行为,那么这是一个非常好的迹象,表明你的泛型方法并不是非常通用的,可能应该以其他方式实现。

答案 1 :(得分:0)

不要使用switch语句。它可能会引入错误并难以维护。 我建议您使用GetGroupById()的默认行为创建一个基类(抽象),并为每个组DashboardGroupType派生类。 当您只需要存储为变量/属性而不必根据值执行任何逻辑时,枚举是合适的。 在派生类中,您可以覆盖默认行为或将其保持为默认值(返回null)。您可以考虑使用空对象设计模式。

当一些变化出现并且变化是唯一不变的时候,你会欣赏设计:)

你可以参考Martin Fowler关于“重构”的书