此问题是我之前发布的帖子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)方法?如果您有任何建议,我将非常感谢您的改进。
提前致谢。
答案 0 :(得分:1)
这段代码对我来说没什么意义。您的通用返回IList<G>
,但该列表只添加了一个项目。有时该项目为null
(或default<G>
,当null
为参考类型时,该项为G
。
我无法想象为什么开发人员支持GetGroupById
泛型方法,这样做比使用单独的方法更复杂。也就是说,为什么没有GetFacilities
,GetCustomers
等?
也许他们更喜欢使用单一服务方法将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关于“重构”的书