Шаблон Specification

Posted: Январь 4, 2011 in .NET, Паттерны

Фреймворк:

    public interface ISpecification<T>
        where T : class
    {
        ISpecification<T> And(ISpecification<T> spec);
        ISpecification<T> Or(ISpecification<T> spec);
        ISpecification<T> Not(ISpecification<T> spec);
        bool IsSatisfiedBy(T candidate);
    }

    public abstract class Specification<T> : ISpecification<T>
        where T : class
    {
        public ISpecification<T> And(ISpecification<T> spec)
        {
            return new AndSpecification<T>(this, spec);
        }

        public ISpecification<T> Or(ISpecification<T> spec)
        {
            return new OrSpecification<T>(this, spec);
        }

        public ISpecification<T> Not(ISpecification<T> spec)
        {
            return new NotSpecification<T>(this);
        }

        public abstract bool IsSatisfiedBy(T candidate);
    }

    public abstract class CompositeSpecification<T> : Specification<T>
        where T : class
    {
        protected readonly Specification<T> left;
        protected readonly ISpecification<T> right;

        public CompositeSpecification(Specification<T> left, ISpecification<T> right)
        {
            this.left = left;
            this.right = right;
        }
    }

    public class AndSpecification<T> : CompositeSpecification<T>
        where T : class
    {
        public AndSpecification(Specification<T> left, ISpecification<T> right)
            : base(left, right)
        {
        }

        public override bool IsSatisfiedBy(T candidate)
        {
            return left.IsSatisfiedBy(candidate) && right.IsSatisfiedBy(candidate);
        }
    }

    public class NotSpecification<T> : Specification<T>
        where T : class
    {
        private readonly Specification<T> specification;

        public NotSpecification(Specification<T> specification)
        {
            this.specification = specification;
        }
        public override bool IsSatisfiedBy(T candidate)
        {
            return !specification.IsSatisfiedBy(candidate);
        }
    }

    public class OrSpecification<T> : CompositeSpecification<T>
        where T : class
    {
        public OrSpecification(Specification<T> left, ISpecification<T> right)
            : base(left, right)
        {

        }
        public override bool IsSatisfiedBy(T candidate)
        {
            return left.IsSatisfiedBy(candidate) || right.IsSatisfiedBy(candidate);
        }
    }

Конкретные спецификации:

 public class DbUniqueSteamIdSpecification : Specification<Claim>
    {
        public override bool IsSatisfiedBy(Claim candidate)
        {
           return !ValidationService.HasParticipantPropertyValueInDB("SteamID", candidate.SteamID);
        }
    }

 public class DbUniqueIcqSpecification : Specification<Claim>
    {
        public override bool IsSatisfiedBy(Claim candidate)
        {
            return !ValidationService.HasParticipantPropertyValueInDB("ICQ", candidate.ICQ);
        }
    }

 public class DbUniqueClaimSpecification : Specification<Claim>
    {
        readonly DbUniqueIcqSpecification icq = new DbUniqueIcqSpecification();
        readonly DbUniqueSteamIdSpecification steamID = new DbUniqueSteamIdSpecification();

        public override bool IsSatisfiedBy(Claim candidate)
        {
            return icq
                 .And(steamID)
                 .IsSatisfiedBy(candidate);
        }
    }
Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s