当前访客身份:游客 [ 登录 | 加入开源中国 ]

代码分享

当前位置:
代码分享 » C#  » 编程基础
予沁安

DDD之砖:时段YearMonthRange

予沁安 发布于 2013年01月09日 7时, 0评/192阅
分享到: 
收藏 +0
2
继上个代码分享,年月类作为基本概念,这有更进一步的扩展应用:时间段.
场景:
 某员工从2011年一月,加入公司以来 每个月 工资6000, 去年3月开始开始加到8000。如何才能表示这个概念/数据。第一个定义就需要用到今天的YearMonthRange.

        2011.year(1).to(2012.year(3))

标签: <无>

代码片段(6) [全屏查看所有代码]

1. [代码]构建YearMonthRange的语法测试代码     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

public class When_initalize_year_month_range:YearMonthRangeSpecs
    {
        private Because of =
            () => subject = 2011.year(2).to(2012.year(10));

        private It start_month_should_assigned =
            () => subject.Begining.ShouldEqual(2011.year(2));

        private It end_month_should_assigned =
            () => subject.Ending.ShouldEqual(2012.year(10));

    }

2. [代码]一个时段是否包含某一个月份     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

public class When_contains
        :YearMonthRangeSpecs
    {
        private Establish context =
            () => subject = 2011.year(2).to(11);

        private It should_contian_month_in_middle =
            () => subject.contains(2011.year(5)).ShouldBeTrue();


        private It should_not_contian_month_after =
                    () => subject.contains(2011.year(12)).ShouldBeFalse();


    }

3. [代码]年月时段枚举每个月。如1月到4月,分别列出1月, 2月,3月和4月.这个比较强,体现了定制月份为基本类型的威力     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

public class When_iterate_year_month:YearMonthRangeSpecs
    {
        private Establish context =
            () => subject = 2011.year(2).to(2011.year(4));

        private It should_contain_teach_month_in_range =
            () => subject.ShouldContainOnly(2011.year(2), 2011.year(3), 2011.year(4));
    }

4. [代码]两个时段是否有交集,这个也很强。     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

 public class When_intersect
    {
       
        
        private It eternal_intersect_anything_is_still_it =
            () => YearMonthRange.Eternal.intersect(2011.year(1).to(2011.year(12)))
                      .ShouldEqual(2011.year(1).to(2011.year(12)));

        private It anything_intersect_eternal_is_still_it =
            () => (2011.year(1).to(2011.year(12))).intersect(YearMonthRange.Eternal)
                      .ShouldEqual(2011.year(1).to(2011.year(12)));

        private It early_year_month_intersect_late_year_month =
            () => 2010.year(1).to(2010.year(12))
                      .intersect(2011.year(1).to(2011.year(12)))
                      .is_empty().ShouldBeTrue();

        private It late_year_month_intersect_early_year_month =
            () => 2012.year(1).to(2012.year(12))
                      .intersect(2011.year(1).to(2011.year(12)))
                      .is_empty().ShouldBeTrue();

        private It cross_year_months_left_ealier =
            () => 2011.year(1).to(2011.year(6))
                      .intersect(2011.year(4).to(2011.year(12)))
                      .ShouldEqual(2011.year(4).to(2011.year(6)));                  
    }

5. [代码]两个特例从不和永远     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

public static YearMonthRange Empty = new YearMonthRange(YearMonth.FarFuture,YearMonth.FarPast);
        public static YearMonthRange Eternal =new YearMonthRange(YearMonth.FarPast,YearMonth.FarFuture);

6. [代码]最后,完整实现代码发放     跳至 [1] [2] [3] [4] [5] [6] [全屏预览]

using System;
using System.Collections;
using System.Collections.Generic;
using Skight.Arch.Domain.Interfaces;

namespace Skight.Arch.Domain.Entities
{
    public struct YearMonthRange
        :IEnumerable<YearMonth> ,IComparable<YearMonthRange>,Range<YearMonth>
    {
        private YearMonth begining;
        private YearMonth ending;
        public YearMonth Begining { get { return begining; } }
        public YearMonth Ending { get { return ending; } }
        public static YearMonthRange Empty = new YearMonthRange(YearMonth.FarFuture,YearMonth.FarPast);
        public static YearMonthRange Eternal =new YearMonthRange(YearMonth.FarPast,YearMonth.FarFuture);
        internal YearMonthRange(YearMonth _begining, YearMonth _ending) 
        {
            this.begining = _begining;
            this.ending = _ending;
        }
        public static YearMonthRange of(YearMonth start,YearMonth end)
        {
            if (start.is_later_than(end))
                return Empty;
            if (start.Equals(YearMonth.FarFuture))
                return Empty;
            if (end.Equals(YearMonth.FarPast))
                return Empty;

            return new YearMonthRange(start,end);
        }

        public bool is_empty()
        {
            return begining.is_later_than(ending);
        }
        public YearMonthRange intersect(YearMonthRange other)
        {
            if (!is_overlap(other))
                return Empty;
            return begining.get_later(other.begining)
                .to(ending.get_ealier(other.ending));
        }
        public bool is_overlap(YearMonthRange other)
        {
            if (is_empty() || other.is_empty())
                return false;
            if (ending.is_ealier_than(other.begining))
                return false;
            if (begining.is_later_than(other.ending))
                return false;
            return true;
        }
        public YearMonthRange gap(YearMonthRange other)
        {
            if (is_overlap(other))
                return Empty;
            if (is_empty() || other.is_empty())
                return Empty;
            return ending.get_ealier(other.ending).get_next()
                .to(begining.get_later(other.begining).get_last());
        }
        public bool containing(YearMonthRange other)
        {
            if (other.is_empty())
                return true;
            if (other.begining.is_ealier_than(Begining))
                return false;

            if (other.Ending.is_later_than(Ending))
                return false;

            return true;
        }

        public IEnumerator<YearMonth> GetEnumerator()
        {
            return new DiscreteEnumerator<YearMonth>(Begining, Ending);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public int CompareTo(YearMonthRange other)
        {
            return begining.CompareTo(other.begining);
        }

        public bool contains(YearMonth value)
        {
            return !Begining.is_later_than(value) && !Ending.is_ealier_than(value);
        }

        public override string ToString()
        {
            return string.Format("<{0},{1}>", begining, ending);
        }

        public YearMonthRange extend(YearMonthRange other)
        {
            if (is_empty())
                return other;
            if (other.is_empty())
                return this;
            return begining.get_ealier(other.begining)
                .to(ending.get_later(other.ending));
        }

        
    }
}


开源中国-程序员在线工具:Git代码托管 API文档大全(120+) JS在线编辑演示 二维码 更多»