我应该将此方法放在我的业务对象或服务中,还是制作扩展方法

时间:2013-02-26 15:34:02

标签: c# oop

在我的PeriodService中,我有这个方法:

private IEnumerable<DateTime> GetAllWeekStartingDays(DateTime start, DateTime end, DayOfWeek firstDayOfWeek)
        {
             return Enumerable
                    .Range(0, end.Subtract(start).Days + 1).Select(offset => start.AddDays(offset))
                    .Where(d => d.DayOfWeek == firstDayOfWeek);             
        }

firstDayOfWeek是来自业务对象XXX的参数。上面的方法让我整天都可能是在一个时间内的星期一/星期日。

我应该将此方法放在我的Period Service(它是atm)中作为私有实例方法,还是作为公共静态方法放入我的业务对象Period.cs中,或者使用我真正不喜欢的扩展方法(hard跟踪/找到他们......)

3 个答案:

答案 0 :(得分:1)

如果您是SRP的粉丝,那么您将此信息放入您的期间服务中。这是因为它会为期间服务提供另一个改变的理由。例如,如果此方法将来会出现某种时区问题。

如果您认为某个扩展方法过于隐藏,可以将其重构为DateService类,您可以将其注入到期间服务中。

<强>更新: 根据我的评论,如果选项是开放的,我会选择使用扩展方法:

public static IEnumerable<DateTime> GetAllWeekStartingDays(this DateTime start, DateTime end, DayOfWeek firstDayOfWeek)
        {
             return Enumerable
                    .Range(0, end.Subtract(start).Days + 1).Select(offset => start.AddDays(offset))
                    .Where(d => d.DayOfWeek == firstDayOfWeek);             
        }

答案 1 :(得分:1)

Period类不适合此方法,期间:)。它不是Period行为,因为它不依赖于Period状态。这就是OO简而言之:结合状态和行为。 Period 可以拥有类似

的方法
IEnumerable<DateTime> GetWeekStartingDays(DayOfWeek firstDayOfWeek)

并使用自己的开始和结束日期(假设它们在那里)来返回结果。

它可能属于PeriodService。服务通常是具有某些依赖关系的类,如存储库或Web服务,并且基本上充当这些依赖关系的包装器。不使用这些依赖关系的方法只会使服务“太忙”并且通常属于其他地方,除了支持服务的公共方法的私有实用程序方法。因此,如果您的方法仅用作PeriodService中的私有方法,那么它就是它所属的位置,因为它的范围(私有)尽可能小。否则我会把它变成Eli Gassert建议的内部(?)静态实用方法。

答案 2 :(得分:0)

我们能看到你是怎么称呼的吗?

我的意思是,我觉得你已经有一个IEnumerable<DateTime>来拨打电话,每次你拨打电话,你都会重复工作,找出开始和结束日期。在这种情况下,使用IEnumerable<DateTime>的扩展方法可以避免重复自己。

public static IEnumerable<DateTime> GetDays(this IEnumerable dates, DayOfWeek day)
{
     var start = dates.Min();
     var end = dates.Max();
     return Enumerable
            .Range(0, end.Subtract(start).Days + 1).Select(offset => start.AddDays(offset))
            .Where(d => d.DayOfWeek == day);             
}

然后你可以简单地称之为:

var mondays = mydates.GetDays(DayOfWeek.Monday);

如果你仍然坚持使用前一个,你可以简单地覆盖:

private IEnumerable<DateTime> GetDays(DateTime start, DateTime end, DayOfWeek day)
{
    return new List<DateTime>(){ start, end }.GetDays(day);
}

注意我重命名了你的方法,因为它推断的目的是比方法的功能更窄。换句话说,您可以使用相同的方法获取范围内的任何工作日,而不仅仅是一周的开始日期。例如,这会阻止其他程序员创建一种新的方法来获取星期三。