实现之间的命名空间差异是否可以被概括/抽象/重构?

时间:2011-05-18 12:40:09

标签: .net generics refactoring performance theory

以下是界面的三个实现。实现1和实现2之间的唯一区别是包含ItemWrapper的命名空间。可以使用泛化或其他东西重构吗?

interface IItemProvider {
    object GetItem(Item item);
}

//1
class SomeNamespaceProvider : IItemProvider {
    object GetItem(Item item) {
        return SomeNamespace.ItemWrapper.GetItem(item);
    }
}

//2
class OtherNamespaceProvider : IItemProvider {
    object GetItem(Item item) {
        return OtherNamespace.ItemWrapper.GetItem(item);
    }
}

//3
class TotallyDifferentProvider : IItemProvider {
    object GetItem(Item item) {
        return DifferentItemRetriever(item);
    }
}

2 个答案:

答案 0 :(得分:1)

根据您的说明,我们了解您在SomeNamespace.ItemWrapperOtherNamespace.ItemWrapper类中有静态方法,并且它们没有实现IItemProvider接口。您希望将这些静态方法转换为实例方法,但您不知道如何执行此操作。

如果类SomeNamespace.ItemWrapperOtherNamespace.ItemWrapper不是静态的,您可以明确地实现IItemProvider

namespace SomeNamespace
{
    public class ItemWrapper: IItemProvider
    {
        public static object GetItem(TaskRunProcessor.Test.Item item)
        {
            return null;
        }

        object IItemProvider.GetItem(Item item)
        {
            return ItemWrapper.GetItem(item);
        }
    }
}

如果他们必须保持静态或因任何原因无法访问代码,我会推荐一些功能方法:

public class GenericProvider : IItemProvider
{
    private Func<Item, object> m_Retriever;

    public GenericProvider(Func<Item,object> retriever)
    {
        if (retriever == null) throw new ArgumentNullException("retriever");
        m_Retriever = retriever;
    }
    object GetItem(Item item)
    {
        return m_Retriever(item);
    }
}

然后你就可以像这样使用`GenericItemProvider':

public class ItemProvderClient
{
    public void Use()
    {
        IItemProvider provider1 = new GenericProvider(SomeNamespace.ItemWrapper.GetItem);
        IItemProvider provider2 = new GenericProvider(OtherNamespace.ItemWrapper.GetItem);

        provider1.GetItem(null);
        provider2.GetItem(null);
    }
}

在这两个解决方案中,不需要为第一个地方的SomeNamespaceProvider类创建更多类evey名称空间的类。

答案 1 :(得分:1)

这是一种方式:

abstract class ItemWrapper {
    public abstract object GetItem(Item item);
}

class OtherNamespaceItemWrapper : ItemWrapper {
    public override object GetItem(Item item) {
        return OtherNamespace.ItemWrapper.GetItem(item);
    }
}

class SomeNamespaceItemWrapper : ItemWrapper {
    public override object GetItem(Item item) {
        return SomeNamespace.ItemWrapper.GetItem(item);
    }
}

然后:

class NamespaceProvider<T> where T : ItemWrapper, new() {
    private readonly ItemWrapper itemWrapper;
    public NamespaceProvider() {
        this.itemWrapper = new T();
    }

    public object GetItem(Item item) {
        return this.GetItem(item);
    }
}

class SomeNamespaceProvider : NamespaceProvider<SomeNamespaceItemWrapper> { }
class OtherNamespaceProvider : NamespaceProvider<OtherNamespaceItemWrapper> { }