Jaka jest różnica między wzorem fabrycznym a fabryką abstrakcyjną?

40

W końcu zacząłem poważnie próbować nauczyć się kilku podstawowych wzorców (bardzo późno w karierze, ale to inna historia), staram się omijać różnice między wzorcem fabrycznym a fabryką abstrakcyjną.

Jakie są kluczowe różnice między tymi dwoma wzorami?

Rozumiem, że Metoda Fabryczna tworzy obiekty poprzez dziedziczenie, a Abstract Factory robi to poprzez kompozycję obiektów, ale z praktycznego punktu widzenia wciąż mam problemy z wizualizacją, w jaki sposób każda z nich działa.

Phil.Wheeler
źródło
2
Aby wyjaśnić, czy masz na myśli „metodę fabryczną”, kiedy mówisz „wzór fabryczny”? Jeśli mówisz o wzorach Gang of Four, nie ma wzorca fabrycznego, ale istnieją abstrakcyjne wzorce fabryczne i metoda fabryczna.
Thomas Owens
Tak - metoda fabryczna.
Phil.Wheeler
3
Szczerze mówiąc, te dwa wyrażenia wydają się być dość często zamienione.
Phil.Wheeler
1
Ach, metoda fabryczna. Obejście tego, że newnie jest to metoda (w niektórych - co prawda powszechnych - systemach obiektowych).
Donal Fellows,

Odpowiedzi:

44

Factory Method jest zwykle podzielone na kategorie według instrukcji switch gdzie każdy przypadek zwraca inną klasę, za pomocą tego samego interfejsu użytkownika root tak, że kod wywołujący nie musi podejmować decyzje dotyczące realizacji.

Pomyśl o fabryce walidatora kart kredytowych, która zwraca inny walidator dla każdego rodzaju karty.

public ICardValidator GetCardValidator (string cardType)
{
    switch (cardType.ToLower())
    {
        case "visa":
            return new VisaCardValidator();
        case "mastercard":
        case "ecmc":
            return new MastercardValidator();
        default:
            throw new CreditCardTypeException("Do not recognise this type");
    }
}

Abstract Factory jest, gdy masz kilka klas fabrycznych beton (nie fabryczne metody) pochodzące z jednego interfejsu, który może wrócić wiele różnych typów z różnych metod.

Pomyśl o menedżerze szachów z inną klasą dla każdego zestawu wariantów zasad.

public class StandardChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class HexagonalChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new HexagonalChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new HexagonalChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new StandardMoveClock();
    }
}

public class SpeedChessRulesFactory : IChessRulesFactory
{
    public IBoardMapper GetBoardMapper()
    {
        return new StandardChessBoardMapper();
    }

    public IKingMover GetKingMover()
    {
        return new StandardChessKingMover();
    }

    public IMoveClock GetMoveClock()
    {
        return new SpeedChessMoveClock();
    }
}

Fabryka abstrakcyjna, podobnie jak strategia, jest często wybierana przy użyciu metody fabrycznej, ale nie jest konieczne łączenie ich, więc jest to jej własny wzór.

pdr
źródło
3
Czy to wyjaśnienie metody Factory jest prawidłowe? Co się dzieje z „Wzorzec metody fabryki opiera się na dziedziczeniu, ponieważ tworzenie obiektów jest delegowane do podklas, które implementują metodę fabryki do tworzenia obiektów”. Tak więc przykład bardziej przypomina fabrykę statyczną.
SerG
@SerG Cóż, uczciwie, wybrałeś ten cytat z Wikipedii na stronie, która trzy lata temu czytała inaczej. Twierdziłbym, że obecna strona Wikipedii zaprzecza sobie w kilku miejscach, ale nie mam ochoty brać udziału w rozbieraniu tego na części. Z perspektywy czasu chciałbym przyznać, że podany tu przykład jest specyficznym rodzajem Metody Fabrycznej, znanej jako Sparametryzowana Metoda Fabryczna. Ale kwestia różnicy między metodą fabryczną a fabryką abstrakcyjną dotyczy wszystkich rodzajów metod fabrycznych.
pdr
2
To samo stwierdzenie, co mój cytat, istnieje w „Wzorcach projektowych” GoF. I tam również opisano sparametryzowane FM.
SerG
Ważną częścią jest to, że fabryka da dzwoniącemu odpowiedni obiekt, w zależności od konkretnej sytuacji, a dzwoniący nie musi wiedzieć, jaka jest dokładnie klasa tego obiektu i nie musi wiedzieć, w jaki sposób dany obiekt został wybrany, o ile obiekt obsługuje interfejs, o którym dzwoniący wie.
gnasher729,
W odpowiedzi należy wyraźnie zaznaczyć, że twój przykład nie jest typowym wzorcem metod fabryki, ale jakąś specjalizacją o nazwie sparametryzowana metoda fabryki. I napisz o definicji typowej metody fabrycznej, ponieważ jest ona obecnie niewłaściwa. Właśnie uczyłem się o wzorcu metody fabrycznej, zrozumiałem wszystko, a potem przeczytałem tę odpowiedź, która pokazuje wzorzec metody fabrycznej jako coś innego i byłem zdezorientowany. Nie ma informacji o tym, że ten przykład nie jest typowym wzorem metody fabrycznej. Dzięki SerG za wyjaśnienie tego w komentarzu.
ctomek