/// <summary>判断两个区间是否重叠 /// </summary> /// <param name="segment1"></param> /// <param name="segment2"></param> /// <returns></returns> private bool IsSegmentIntersect(Segment segment1, Segment segment2) { return (segment1.StartNo > segment2.StartNo && segment1.StartNo < segment2.EndNo) || (segment1.EndNo > segment2.StartNo && segment1.EndNo < segment2.EndNo) || (segment1.StartNo <= segment2.StartNo && segment1.EndNo >= segment2.EndNo) || (segment1.StartNo >= segment2.StartNo && segment1.EndNo <= segment2.EndNo); }
/// <summary>判断当前座位是否可以出售给给定的区间 /// </summary> /// <param name="segment"></param> /// <returns></returns> public bool CanSellToSegment(Segment segment) { //如果当前座位的已出售区间中有任何一个区间和当前区间重叠,则认为当前座位不允许出售给当前区间 foreach (var soldSegment in _soldSegments) { if (IsSegmentIntersect(soldSegment, segment)) { return false; } } return true; }
/// <summary>将给定座位出售给给定的订票区间 /// </summary> /// <param name="seat"></param> /// <param name="segment"></param> /// <param name="atomSegments"></param> private void SellSeat(Seat seat, Segment segment, IEnumerable<Segment> atomSegments) { foreach (var atomSegment in atomSegments) { _atomSegments[atomSegment] = _atomSegments[atomSegment] - 1; } seat.AddSoldSegment(segment); if (!_soldSeats.ContainsKey(seat.No)) { _soldSeats.Add(seat.No, seat); _cleanSeats.Remove(seat.No); } }
/// <summary>添加一个已出售的区间 /// </summary> /// <param name="segment"></param> public void AddSoldSegment(Segment segment) { _soldSegments.Add(segment); }
/// <summary>为给定的订票区间选择一个可用的座位,优先回收已出售的座位 /// </summary> /// <param name="segment"></param> /// <returns></returns> private Seat SelectSeat(Segment segment) { //优先回收已出售的座位 foreach (var seat in _soldSeats.Values) { if (seat.CanSellToSegment(segment)) { return seat; } } //如果已出售的座位不符合当前区间的出售条件,则尝试从座位池取出第一个座位进行出售 return _cleanSeats.Values.FirstOrDefault(); }
/// <summary>获取给定区间的原子区间列表 /// </summary> /// <param name="segment"></param> /// <returns></returns> private IEnumerable<Segment> GetAtomSegments(Segment segment) { return _atomSegments.Where(x => x.Key.StartNo >= segment.StartNo && x.Key.EndNo <= segment.EndNo).Select(x => x.Key).ToList(); }
/// <summary>创建一张票 /// </summary> /// <param name="seat"></param> /// <param name="segment"></param> /// <returns></returns> private Ticket CreateTicket(Seat seat, Segment segment) { var startStation = _stations.Single(x => x.No == segment.StartNo); var endStation = _stations.Single(x => x.No == segment.EndNo); return new Ticket(seat.No, startStation, endStation); }
/// <summary>订票领域方法,实现订票的核心业务逻辑 /// </summary> /// <param name="segment"></param> /// <returns></returns> public Ticket BookTicket(Segment segment) { var atomSegments = GetAtomSegments(segment); if (!IsAllAtomSegmentHaveSeat(atomSegments)) { return null; } var seat = SelectSeat(segment); if (seat != null) { SellSeat(seat, segment, atomSegments); return CreateTicket(seat, segment); } return null; }
private static bool IsEqual(Segment left, Segment right) { if (ReferenceEquals(left, null) ^ ReferenceEquals(right, null)) { return false; } return ReferenceEquals(left, null) || left.Equals(right); }