通用基类包装嵌套泛型类以减少类型参数规范:此模式是否有名称?

时间:2013-04-18 11:57:57

标签: c# generics design-patterns naming nested-class

好的问题标题远非不言自明。我看到自己经常这样做:

来自this answer

public static class Equality<T>
{
    public static IEqualityComparer<T> CreateComparer<K>(Func<T, K> keySelector)
    {
        return new KeyEqualityComparer<K>(keySelector);
    }



    class KeyEqualityComparer<K> : IEqualityComparer<T>
    {
        readonly Func<T, K> keySelector;

        public KeyEqualityComparer(Func<T, K> keySelector)
        {    
            this.keySelector = keySelector;
        }

        public bool Equals(T x, T y)
        {
            ----
        }

        public int GetHashCode(T obj)
        {
            ....
        }
    }
}

我做了什么:我需要调用一个实现细节KeyEqualityComparer<T, K>

new KeyEqualityComparer<Person, int>(p => p.ID);

通过将其嵌套为私有类,我不仅隐藏了实现(内部类的公共构造函数现在也模糊不清),而且语法更好:

Equality<Person>.CreateComparer(p => p.ID);

请注意,我没有从父类继承嵌套类(这是静态的)。

或者有时我看到自己doing this

public abstract class Equater<T> : IEqualityComparer<T>
{
    public static Equater<T> Create<TKey>(Func<T, TKey> keySelector)
    {
        return new Impl<TKey>(keySelector);
    }

    public abstract bool Equals(T x, T y);

    public abstract int GetHashCode(T obj);



    class Impl<TKey> : Equater<T>
    {
        readonly Func<T, TKey> keySelector;

        public Impl(Func<T, TKey> keySelector)
        {
            this.keySelector = keySelector;
        }

        public override bool Equals(T x, T y)
        {
            ----
        }

        public override int GetHashCode(T obj)
        {
            ....
        }
    }
}

另一个类似的here

public class Accessor<S>
{
    public static Accessor<S, T> Create<T>(Expression<Func<S, T>> memberSelector)
    {
        return new GetterSetter<T>(memberSelector);
    }

    class GetterSetter<T> : Accessor<S, T>
    {
        public GetterSetter(Expression<Func<S, T>> memberSelector) : base(memberSelector)
        {

        }
    }
}

public class Accessor<S, T> : Accessor<S>
{
    Func<S, T> Getter;
    Action<S, T> Setter;

    public bool IsReadable { get; private set; }
    public bool IsWritable { get; private set; }
    public T this[S instance]
    {
        get
        {
            if (!IsReadable)
                throw new ArgumentException("Property get method not found.");

            return Getter(instance);
        }
        set
        {
            if (!IsWritable)
                throw new ArgumentException("Property set method not found.");

            Setter(instance, value);
        }
    }

    protected Accessor(Expression<Func<S, T>> memberSelector) //access not given to outside world
    {
        ----
    }

}

请注意,在这两种情况下,我从包装类继承。所以现在我不仅得到了前者的好处,而且还可以维护这样的列表:

List<Equater<Person>> { persons with different implementations };

它不时地帮助我。 所以我很想知道这个模式是否有名称?

3 个答案:

答案 0 :(得分:2)

我认为这很像Class Clusters pattern,它基于抽象工厂模式。

答案 1 :(得分:1)

我认为你没有遵循任何一种模式。

我想说通过使用单个“Create”方法替换多个“CreateComparer”方法,您刚刚简化了一个Creation Method模式。从某种意义上说,你可以说它是一种工厂模式?!或者也许是一个Builder模式 - 我猜这个模式是开放的吗?!

通过在“Equater”中嵌入“Impl”,您可以按照Command模式 - 封装方法调用,以便您的调用代码不知道 它是如何完成的。

无论如何,对不起,我没有比这更有帮助或给你一个明确的答案!无论如何,希望它有所帮助!

答案 2 :(得分:0)

正如Bertie正确指出的那样,我可能没有在这里跟随任何一个模式。

我想说通过将具体实现的实例化委托给CreateComparer方法,我刚刚简化了对象创建 - 它位于Creation Method patterns之下。通过为对象实例化提供静态函数,它有点像工厂模式 - 特别是this variant of Factory Method

Impl继承Equater我有点跟随Abstract Factory模式 - 其中Equater是工厂工厂,而Impl是其实施Impl本身回来了,除了Impl实际上没有创建任何其他对象(换句话说Impl并不是一个工厂),但自己实例化通过构造函数。所以从严格意义上说,它不是抽象工厂模式,但如果Impl可以有一个方法来调用自身的构造函数并返回一个实例,那么它将更接近。

同样通过嵌入和隐藏实现细节(嵌套类本身),暴露的类(父类)伪造到外部世界,好像它正在做它的工作。这就是所谓的Delegation Pattern

至于隐藏嵌套泛型类中泛型类的实现的名称,以便为方法调用提供更容易的签名,我认为不存在。即使存在任何名称,它也必须非常特定于语言(或类似语言),因为涉及诸如泛型/类型推断等语言构造。 Eric Lippert在嵌套类here中发现了相同的用法,尽管它不是泛型相关的,他称之为工厂模式。