从数据库读取创建正确的具体类型

时间:2015-08-05 20:00:33

标签: c# oop design-patterns abstract-class

我正在研究的项目将受益于增加一点抽象,我面临着一个我似乎无法过去的问题。

基本上我们有可以分配和消费的服务,但消费的速度都有所不同。这种区别对于报告和安排这些服务的消耗很重要。

我不确定如何从数据库中获取数据,并确保创建正确的具体类型。我是否在思考这个问题,我能做些什么呢?我唯一能想到的就是让switch语句根据指定的时间单位确定要制作哪种类型,但这看起来很草率。

UnitInterval(我欢迎将其重命名为似乎不那么混乱的东西),应该保留服务的消费单位(1,15,30,60),然后UnitSize将是分钟,小时或天。 UnitSizes保存在参考表中,并使用相应的日,分,小时文本标识。因此,在我的表中,Minute的ID = 1,Hour = 2,Day = 3,并且根据是否需要调整这些间隔,它们可以在将来使用。

如何从数据库中获取类似UnitSize的内容并确保正确实施?我只是以完全错误的方式解决这个问题吗?

基本上我的最终游戏是,我将有另一个只包含List<WorkableService>的课程,我可以用它来发出一个包含正确单位,任何成本,持续时间等的报告。

public abstract class WorkableService
{
    public int UnitSizeId { get; set; }
    public string UnitSizeText { get; set; } 

    public double UnitInterval { get; set; }
    public abstract TimeSpan Duration { get; }
    public double UnitsAvailable { get; set; }
    public double Adjustment { get; set; }
    public decimal Rate { get; set; }
}

public class MinuteService : WorkableService
{
    public override TimeSpan Duration
    {
        get
        { 
            return TimeSpan.FromMinutes(UnitInterval); 
        }
    }
}

public class HourlyService : WorkableService
{
    public override TimeSpan Duration
    {
        get 
        {
            return TimeSpan.FromHours(UnitInterval);        
        }
    }
}

public class DailyService : WorkableService
{
    public override TimeSpan Duration
    {
        get 
        {
            return TimeSpan.FromDays(UnitInterval);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果您在编译时确定所有可能需要的选项,那么switch方法是完全有效的。维基百科factory pattern提供更多基本信息,但是打开枚举值或字符串标识符是一般概念。

或者,查看Activator.CreateInstance,您可以根据可以从数据库动态加载的类型名称来创建新对象。我们在某些情况下这样做,让我们添加新支持的类型,而无需重新编译基本服务。

答案 1 :(得分:0)

您称之为草率的switch语句称为Factory模式。假设您的WorkableService基础构造函数需要UnitInterval

static class WorkableServiceFactory
{
    public static WorkableService Get(int unitSizeId, double unitInterval)
    {
        switch (unitSizeId)
        {
            case 1:
                return new MinuteService(unitInterval);
            case 2:
                return new HourlyService(unitInterval);
            case 3:
                return new DailyService(unitInterval);
            default:
                throw new ArgumentOutOfRangeException("unitSizeId");
        }
    }
}

我通常不是工厂的粉丝(出于某种原因,他们是书中每个Java EE笑话的对象),但这实际上是一个有效的场景。