Spiga

模式开发之旅(15):组合模式

2010-08-06 15:24:29

组合模式: 将对象组合成树型结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式的设计思路,与其说是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

利用组合模式实现DDD中的规约

//规约基类
public interface ISpecification<TEntity> where TEntity : class
{
    Expression<Func<TEntity, bool>> SatisfiedBy();
}

//组合模式基类
public abstract class CompositeSpecification<TEntity> where TEntity : class
{
    // Check if this specification is satisfied by a specific expression lambda
    public abstract Expression<Func<TEntity, bool>> SatisfiedBy();

    public abstract ISpecification<TEntity> LeftSideSpecification { get; }

    public abstract ISpecification<TEntity> RightSideSpecification { get; }
}

public sealed class AndSpecification<T> : CompositeSpecification<T> where T : class
{
    private ISpecification<T> _RightSideSpecification = null;
    private ISpecification<T> _LeftSideSpecification = null;

    public AndSpecification(ISpecification<T> leftSide, ISpecification<T> rightSide)
    {
        if (leftSide == (ISpecification<T>)null)
            throw new ArgumentNullException("leftSide");

        if (rightSide == (ISpecification<T>)null)
            throw new ArgumentNullException("rightSide");

        this._LeftSideSpecification = leftSide;
        this._RightSideSpecification = rightSide;
    }

    public override ISpecification<T> LeftSideSpecification
    {
        get { return _LeftSideSpecification; }
    }

    public override ISpecification<T> RightSideSpecification
    {
        get { return _RightSideSpecification; }
    }

    public override Expression<Func<T, bool>> SatisfiedBy()
    {
        Expression<Func<T, bool>> left = _LeftSideSpecification.SatisfiedBy();
        Expression<Func<T, bool>> right = _RightSideSpecification.SatisfiedBy();

        return (left.And(right));

    }
}

public sealed class OrSpecification<T> : CompositeSpecification<T> where T : class
{
    private ISpecification<T> _RightSideSpecification = null;
    private ISpecification<T> _LeftSideSpecification = null;

    public OrSpecification(ISpecification<T> leftSide, ISpecification<T> rightSide)
    {
        if (leftSide == (ISpecification<T>)null)
            throw new ArgumentNullException("leftSide");

        if (rightSide == (ISpecification<T>)null)
            throw new ArgumentNullException("rightSide");

        this._LeftSideSpecification = leftSide;
        this._RightSideSpecification = rightSide;
    }

    public override ISpecification<T> LeftSideSpecification
    {
        get { return _LeftSideSpecification; }
    }

    public override ISpecification<T> RightSideSpecification
    {
        get { return _RightSideSpecification; }
    }

    public override Expression<Func<T, bool>> SatisfiedBy()
    {
        Expression<Func<T, bool>> left = _LeftSideSpecification.SatisfiedBy();
        Expression<Func<T, bool>> right = _RightSideSpecification.SatisfiedBy();

        return (left.Or(right));

    }
}

以上代码只是规约模式中的局部实现,代码中LeftSideSpecification和RightSideSpecification都是ISpecification泛型类型,而AndSpecification和OrSpecification也都继承ISpecification。因此它们可以相互组合形成树型结构,使用者可以根据自己的需求灵活组装规约。