myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Was genau ist der Vorteil vom Factory-Pattern?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Was genau ist der Vorteil vom Factory-Pattern?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 177
Entwicklungsumgebung: Visual Studio 6.0 Enterprise


JimStark ist offline

Was genau ist der Vorteil vom Factory-Pattern?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

von .NET Entwicklern hört man ja recht oft "new is glue", deswegen wollte ich mich da auch mal etwas weiterbilden :D

Ich habe mal versucht ein einfaches Factory-Pattern umzusetzen. Es sollen (hier als Beispiel) Aktien aus verschiedenen Quellen importiert werden können (Xml, Json, Api,...).

C#-Code:
    // Product:
    public abstract class StockImporter
    {
        public abstract List<Stock> GetStocks();
    }

    // ConcreteProduct:
    public class XmlStockImporter : StockImporter
    {
        public string _file;
        public XmlStockImporter(string fileLocation)
        {
            _file = fileLocation;
        }
        public override List<Stock> GetStocks()
        {
            // lese XML _file...
            return new List<Stock>();
        }
    }

    // Creator:
    public abstract class StockImporterFactory
    {
        public abstract StockImporter GetStockImporter();
    }

    // ConcreteCreator:

    public class XmlStockImporterFactory : StockImporterFactory
    {

        private string _Location;

        public XmlStockImporterFactory(string location)
        {
            _Location = location;
        }
        public override StockImporter GetStockImporter()
        {
            return new XmlStockImporter(_Location);
        }

    }

Möchte ich jetzt den XmlImporter nutzen würde ich den mit meinem Kenntnisstand so erstellen:

C#-Code:
var factory = new XmlStockImporterFactory("C:/test.xml");
StockImporter importer = factory.GetStockImporter();
var stocks = import.GetStocks()...

Ich verstehe jetzt nicht genau was da der Vorteil ist, außer dass ich nicht direkt den XmlStockImporter erzeugen muss. Soll die Factory das "Erzeugen" übernehmen, dass ich bei aufwendigeren DIs mich nur in der Factory kümmere?

Zweite Frage:
Theoretisch bräuchte ich jetzt doch noch eine Factory oder gibt es da eine schönere Lösung?
Z.B. sowas:

C#-Code:
public enum StockImporterType ...

public StockImporterFactoryProvider(StockImporterType type)
{
    select(....) // jeweiligen Typ zurückgeben
}
12.01.2021 16:20 Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 935


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das verstehe ich nicht... Warum verwendest du nicht einfach Dependency injection? Ansonsten würde ich an deiner Stelle die verschiedenen Erzeugungsmuster mal anschauen, da gibt es verschiedene Abstraktionsstufen.
12.01.2021 18:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.447
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Dein Code Beispiel entspricht nicht dem Sinn einer Factory; daher vermutlich das Verständnisproblem.

Wie witte schon gesagt hat, gibt es bei Factories verschiedene Stufen; alle zusammen verfolgen aber den Sinn die Instanziierung abstrakt umzusetzen.
Die am meisten verbreiteten Varianten sind die Vererbung- und die Typ-Implementierung:

Vererbung

C#-Code:
namespace MyCSharp
{
    public interface IFahrzeug { }

    public abstract class FahrzeugFactory
    {
        public abstract IFahrzeug GetFahrzeug();
    }

    public class Auto : IFahrzeug { }

    public class AutoFactory : FahrzeugFactory
    {
        public override IFahrzeug GetFahrzeug() => new Auto();
    }
}

Typ
Wenn also jemand ein Fahrzeug braucht und die konkrete Implementierung egal ist, dann gibt es absolut null Abhängigkeit a) zum Typ und b) zur Erzeugung.

C#-Code:
namespace MyCSharp
{
    public interface IStockTickerSymbolService
    {
        Task<SymbolData> GetSymbolData(string symbol);
    }
    public class ComdirectStockTickerOptions
    {
        public string SymbolUrl = "https://www.comdirect.de/inf/aktien/{0}";
    }
    public class YahooStockTickerSymbolService : IStockTickerSymbolService
    {
        public YahooStockTickerSymbolService(IOptions<YahooStockTickerOptions> optionsAccessor)
    }
    public class ComdirectStockTickerSymbolService : IStockTickerSymbolService
    {
        public ComdirectStockTickerSymbolService(IOptions<ComdirectStockTickerOptions> optionsAccessor)
    }
}

Beispiel aus:  Mit welchem Pattern kann ich generische Links zu versch. (Finanz)Websites herstellen?
Haste aber sicher schon bei Deiner entsprechenden Suche als 4. Treffer (3 Wochen alt) hier im Forum entdeckt.

Im anderen weit verbreiteten Fall hat man die Information, was man erzeugen will, aber nicht das Wissen, um es selbst zu erzeugen (hier die Optionen).

Im Falle von einem Stockticker will ich zB. Informatioinen über eine Aktie haben, die prinzipiell bei jeder API identisch im Format zu haben sind; die API wird aber unterschiedliche angesprochen.

Brauchst dann quasi nur noch die Implementierung, dass Du anhand zB. eines Enum die Instanz von Yahoo oder eben ComDirect bekommst.
Das siehst Du im Beispiel des 5. Treffers aus Deiner sicherlich durchgeführten Forensuche
 Tipp zur Implementierung auswählbarer Hardware API (static class methoden auswählbar)
12.01.2021 18:40 Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 177
Entwicklungsumgebung: Visual Studio 6.0 Enterprise

Themenstarter Thema begonnen von JimStark

JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke euch beiden für die Antworten.

Zitat:
Dein Code Beispiel entspricht nicht dem Sinn einer Factory; daher vermutlich das Verständnisproblem.

Was ist daran falsch, hatte mich sogar an deinem von dir verlinkten Artikel orientiert:
 https://www.dofactory.com/net/factory-method-design-pattern
Verstehe da nicht ganz den Unterschied zu deinem Beispiel außer dem Interface.

Also eine Methode mit einem Switch & enum als Parameter, die mir dann die ConcreteFactory (z.B. AutoFactory) zurückgibt wäre auch eine Factory?
13.01.2021 08:44 Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.688
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

In dem Fall ist das Problem, dass du in deinem Code bereits die konkrete Factory erstellst und und verwendest.

Der Sinn der Factory ist es, dass man eben nicht gegen eine konkrete Implementierung arbeitet sondern gegen das Interface und somit eine austauschbare Basis hat.
Damit kann man wie bei einer Fabrik eben gemeinsame Typen erstellen und diese über ein Interface nutzen und austauschen.
Dadurch muss man auch nicht wissen, wie ein konkreter Typ instanziert wird.
Diese Details können dann auch im Hintergrund verborgen bleiben, was für den Verbraucher i.d.R. egal ist.

Der Verbraucher einer Factory muss dann nur den entsprechenden Typen anfordern, erhält auf seiner Seite dann nur eine Implementierung des Interface.
Dadurch muss der Anwender auch nicht wissen welcher Konkrete Typ vorliegt, solange dieser das zu grunde liegende Interface umsetzt.

Klarer wird es wenn man mit der Factory Method anfängt.
Dort hast du dann eine Methode, die dein Interface liefert.
Per Parameter steuerst du dann, welcher konkrete Typ geliefert werden muss.
Ob das dann ein Enum, string, int oder was auch immer ist, hängt von der jeweiligen Implementierung ab.
Der Verbraucher bekommt dann immer nur sein Interface gegen das er arbeitet.

T-Virus
13.01.2021 09:40 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 177
Entwicklungsumgebung: Visual Studio 6.0 Enterprise

Themenstarter Thema begonnen von JimStark

JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Danke T-Virus.

Ich glaube ich habe es soweit verstanden, der Factory übergebe ich dann z.B. meine Configuration, die Factory kümmert sich dann um die Erzeugung des gewünschten Products und weiß z.B. welche Section für die jeweilige Options genutzt wird und übergibt sie dem Product/erzeugt es.

Danke euch!
13.01.2021 10:24 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum
Antwort erstellen


© Copyright 2003-2021 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 17.01.2021 04:08