Реализация Factory Pattern без отражения - PullRequest
0 голосов
/ 13 марта 2012

Я провожу некоторые исследования вариантов реализации шаблонов проектирования, я натолкнулся на некоторые примеры, реализованные здесь http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern и http://www.oodesign.com/factory-pattern.html.. Моя задача - использовать фабричный шаблон без отражения.В заявленных статьях говорится, что нам нужно регистрировать объекты, а не классы, что мне кажется нормальным и логичным, но, когда я вижу реализацию, я вижу дублирование объектов, например, в приведенном ниже коде

// Factory pattern method to create the product
public IRoomType CreateProduct(RoomTypes Roomtype)
{
    IRoomType room = null;
    if (registeredProducts.Contains(Roomtype))
    {
        room = (IRoomType)registeredProducts[Roomtype];
        room.createProduct();
    }
    if (room == null) { return room; }
    else { return null; }
}

// implementation of concrete product
class NonACRoom : IRoomType
{
    public static void RegisterProduct()
    {
        RoomFactory.Instance().RegisterProduct(new NonACRoom(), RoomTypes.NonAcRoom);
    }
    public void getDetails()
    {
        Console.WriteLine("I am an NON AC Room");
    }
    public IRoomType createProduct()
    {
        return new NonACRoom();
    }
}

, для которого используется метод RegisterProductСаморегистрация, мы должны вызывать его в любом случае перед созданием объекта фабрики, то есть перед тем, как в каком-либо месте в основном классе клиента или где-либо, где это применимо, чтобы обеспечить его вызов.ниже мы создаем новый продукт, а в методе выше мы снова создаем новый продукт, который кажется бессмысленным.любой комментарий тела

Ответы [ 2 ]

0 голосов
/ 13 марта 2012

Я делал нечто подобное в прошлом.По сути, это то, что я придумал (а также покончил со всем перечислением «Type»):

public interface ICreator
{
    IPart Create();
}


public interface IPart
{
    // Part interface methods
}


// a sample creator/part

public PositionPartCreator : ICreator
{
    public IPart Create() { return new PositionPart(); }
}

public PositionPart : IPart
{
    // implementation
}

Теперь у нас есть сама фабрика:

public sealed class PartFactory
{
    private Dictionary<Type, IPartCreator> creators_ = new Dictionary<Type, IPartCreator>();

    // registration (note, we use the type system!)
    public void RegisterCreator<T>(IPartCreator creator) where T : IPart
    {
        creators_[typeof(T)] = creator;
    }


    public T CreatePart<T>() where T: IPart
    {
        if(creators_.ContainsKey(typeof(T))
            return creators_[typeof(T)].Create();
        return default(T);
    }
}

Это по существуизбавляет от необходимости перечисления типа и упрощает работу с:

PartFactory factory = new PartFactory();
factory.RegisterCreator<PositionPart>(new PositionPartCreator());
// all your other registrations



// ... later


IPart p = factory.CreatePart<PositionPart>();
0 голосов
/ 13 марта 2012

Первое творение используется, чтобы дать что-то для работы RegisterProduct.Вероятно, стоимость этого объекта ничтожна.Это делается во время инициализации и не имеет большого значения.

Этот экземпляр необходим, хотя, потому что в C # вам нужен объект для вызова createProduct.Это потому, что вы не можете использовать отражение для хранения ссылки на тип вместо ссылки на объект.

...