工厂的通用实现,用于不同类型的类

时间:2018-03-08 09:41:14

标签: c# design-patterns

我们正在提供一组Entity和Consumer类。调用XConsumer会返回一个XEntity,而调用YConsumer会返回一个YEntity,依此类推。使用相同类型的参数的Consumer类的API是相同的。 Consumer和Entity类不从基类继承,也不实现接口。我想要实现的是通常调用返回特定类型的所需实体的工厂。我目前的实现如下:

static class Factory<TConsumer> where TConsumer : new()
{
 static dynamic Consume(Document document, out List<Error> errors)
 {
   // Common code before calling any consumer goes here
   Stream stream = document.Stream;

   dynamic consumer = new TConsumer();
   return consumer.Consume(stream, out errors);
 }
}

我的调用代码如此

XEntity entity = Factory<XConsumer>.Consume(document, out errors);

注意我只负责Factory类和调用代码,不允许修改Entity和Consumer类。有没有办法让这更好,最好不使用动态?

3 个答案:

答案 0 :(得分:1)

避免反思的一种方法是使用Adapter pattern.

基本上,您所做的是创建一个interface,其中包含consumer类的常用方法和属性,并为实现此接口的每个consumer创建一个包装类。 / p>

通过这种方式,您可以在不使用dynamicreflection的情况下实施您的方法,并保持其安全类型。

当然,缺点是你必须编写(并维护)比目前更多的代码。

答案 1 :(得分:0)

理想情况下,您需要更改实体类,以便它们都实现接口,例如IEntity。工厂应根据某些标准选择消费者,而不是知道您要使用哪个消费者。您可以根据所需的wntiry返回类型做出此决定。

例如:

// you don't necessarily need this interface but it allows a meaningful
// constraint if you apply it to your 'entity' classes. If you can't apply
// this interface to the entity classes then remove the constraints below
public interface IEntity
{
    // things it does
}

public class XEntity : IEntity
{
}

public class YEntity : IEntity
{
}

public interface IConsumer<TEntity> where TEntity : IEntity // remove constraint if required
{
    TEntity Consume(Stream stream, out List<Error> errors);
}

public class XConsumer : IConsumer<XEntity>
{
    public XEntity Consume(Stream stream, out List<Error> errors);
    {
        // something
    }
}

public class YConsumer : IConsumer<YEntity>
{
    public YEntity Consume(Stream stream, out List<Error> errors);
    {
        // something
    }
}

public static class ConsumerFactory
{
    // this will now create a consumer instance based on the entity type
    public static IConsumer<TEntity> Create<TEntity>() where TEntity : IEntity // remove constraint if required
    {
        if (typeof(TEntity) == typeof(XEntity))
            return new XConsumer;
        if (typeof(TEntity) == typeof(YEntity))
            return new YConsumer;
        throw new Exception("Unsupported type");
    }
    public static TEntity Consume<TEntity>(Stream stream, out List<Error> errors) where TEntity : IEntity // remove constraint if required
    {
        return Create<TEntity>().Consume(stream, out errors);
    }
}

用法:

XEntity x = ConsumerFactory.Consume<XEntity>(document, out errors);
YEntity y = ConsumerFactory.Consume<YEntity>(document, out errors);

答案 2 :(得分:0)

没有反映不是我想要的。我将你的回答标记为答案,但我会坚持自己的实施。最初我以为我发布这个问题以防我错过了什么