1

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

这个答案

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);

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

或者有时我看到自己这样做

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)
        {
            ....
        }
    }
}

另一个类似的在这里

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 };

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

4

3 回答 3

2

我认为这很像基于抽象工厂模式的类集群模式。

于 2013-10-31T08:16:05.987 回答
1

我认为您在这里没有遵循任何一种模式。

我想说,通过用一个“Create”方法替换多个“CreateComparer”方法,您只是简化了一个 Creation Method 模式。你可以在某种意义上说这是一种工厂模式?!或者也许是一种建造者模式——我猜那个是可以解释的?!

通过在“Equater”中嵌入“Impl”,您有点遵循命令模式 - 封装方法调用,以便您的调用代码不知道它是如何完成的。

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

于 2013-04-18T12:42:05.050 回答
0

正如伯蒂正确指出的那样,我在这里可能没有遵循任何一种模式。

我想说,通过将具体实现的实例化委托给CreateComparer方法,我刚刚简化了对象创建——它属于Creation Method patterns。通过具有用于对象实例化的静态函数,它有点像工厂模式——特别是工厂方法的这种变体

Impl通过从我继承,Equater我有点遵循了抽象工厂模式——Equater工厂的工厂在哪里,Impl它的实现是为了回馈Impl自己,但Impl实际上并没有创建任何其他对象(换句话说Impl,这并不意味着是一个工厂),但是通过构造函数实例化自己。所以严格意义上来说,它不是抽象工厂模式,但它会更接近于 ifImpl可以有一个方法来调用自己的构造函数并返回一个实例。

同样通过嵌入和隐藏实现细节(嵌套类本身),暴露的类(父类)假装给外界,就好像它正在做它的工作一样。这就是所谓的委托模式

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

于 2013-04-19T09:15:52.747 回答