Inversion of Control Principle in Swift

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Inversion of Control Principle in Swift

    In C# ist es ratsam das Inversion of Control Principle zu befolgen. Man sollte Interfaces statt konkrete Objekte verwenden. Es ist gut für gute Encapsulation und loose coupling of code.
    Außerdem tut man sich beim Unit-Testing und auch Mocking/Dependency Injection leichter.
    Ich habe dazu ein Bsp. angehängt.

    Mit Swift benötige ich ja nicht wirklich ein Mocking Framework. Das geht ja mit einem Dreizeiler (wie unterhalb sichtbar) sehr gut.

    Nun meine Frage: Verwendet man das Inversion of Control Principle auch in Swift (hier Protocols statt Interfaces?) oder gibts andere Techniken? Für Swift habe ich im Web leider nichts gefunden. Für Objective-C hab ich ein paar Artikel gefunden wie bspw. hier:
    danielsaidi.wordpress.com/2014…y-approach-to-ioc-in-ios/

    Ich bin für jede Auskunft dankbar!

    Quellcode

    1. interface ILogWriter
    2. {
    3. void WriteToLog(string message);
    4. }
    5. class DatabaseLogWriter : ILogWriter
    6. {
    7. public void WriteToLog(string message)
    8. {
    9. // make call to webservice and write to database
    10. }
    11. }
    12. class HarddriveLogWriter : ILogWriter
    13. {
    14. public void WriteToLog(string message)
    15. {
    16. File.AppendAllText(@"D:\sample.log", message);
    17. }
    18. }
    19. class LogManager
    20. {
    21. private ILogWriter _logWriter;
    22. public LogManager(ILogWriter logWriter)
    23. {
    24. _logWriter = logWriter;
    25. }
    26. public void WriteToLog(string message)
    27. {
    28. _logWriter.WriteToLog(message);
    29. }
    30. }
    Alles anzeigen

    Swift Mocking:

    Quellcode

    1. class LogWriterMock: ILogWriter {
    2. override func writeToLog(message: String) {
    3. // ...
    4. }
    5. }

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von 99s99m ()

  • Was ist denn der Unterschied zwischen deinen beiden Listings, außer dass die Swift-Klasse kein Teil des Protokolls ist?

    Das Entscheidende in beiden Sprachen ist doch die Abstraktion des Loggings in einer Schnittstelle. Der LogManager macht ja anscheinend nichts wirklich Praktisches und delegiert die einzige Aufgabe auch noch weiter; wie halt Manager so sind. ;) Den kannst du dir sparen.

    Apropos Manager: Das C#-Listing sieht nach ziemlich viel heißer Luft aus. Der LogManager ist ja ein delegierender ILogWriter. Ihm fehlt nur das entsprechende Super-Interface.
    „Meine Komplikation hatte eine Komplikation.“
  • Also IoC hat ja erstmal nix mit der verwendeten Sprache zu tun. Cocoa ist voll davon, Stichwort Delegation, Datasources, NSCoding etc.

    Aber das bedeutet nicht zwangsläufig, für alles und jedes ein interface zu verwenden.

    Gruß, Markus

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Markus Müller () aus folgendem Grund: Rechtschreibfehler korrigiert

  • IOC ist auch nicht die Definition von Protokollen statt Interfaces, sondern verlangt die Definition von Protokollen statt Interfaces, weil das Framework die konkrete Klasse in der Anwendung weder kennen noch vorschreiben kann.

    Die von "Professor Blowing your Mind" vorgestellte, jedoch uralte Idee, für alles erst einmal ein Protokoll zu haben, bedeutet erst einmal mehr Arbeit. Das ist schlecht für die Gesundheit. Es ist nützlich, wenn man solche Fragestellungen wie im ersten Absatz hat. Innerhalb der eigenen App mit dem weitreichend bekannten Sourcecode ist es eher unnütz.

    Wie bei jedem Muster sollte man bedenken, welches Problem es zu lösen gilt und wieso die Leute auf diese Lösung verfallen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Danke @all für eure Antworten!
    Das Bsp. diente nur zur Klarstellung meiner Frage. Ich habe dieses jz noch erweitert. Ich weiß, dass die LogManager Klasse davor keinen Sinn ergeben hat. ;)
    Wiegesagt, war das ja nur ein Codeschnipsel.

    Meine Frage bezog sich darauf, ob dies in Swift so ähnlich wie in C# gelöst wird bzw. ob es gebräuchlich in Swift ist.

    Markus Müller schrieb:

    Aber das bedeutet nicht zwangsläufig, für alles und jedes ein interface zu verwenden.
    Gute Encapsulation und loose coupling habe ich damit schon erreicht und beim Mocking tu ich mir auch leichter.

    Amin Negm-Awad schrieb:

    Wie bei jedem Muster sollte man bedenken, welches Problem es zu lösen gilt und wieso die Leute auf diese Lösung verfallen.
    Das sehe ich auch so... darum auch meine Frage.
  • Worauf ich – und mutmaßlich auch Markus Müller – hinaus wollten: Du brauchst innerhalb deiner App nur selten Loose-Coupling.

    Irgendwann schreiben die Leute nur noch Code, den sie in jedem Projekt weiterverwenden könnten, was jedoch nie geschehen wird, weil sie mit dem Schreiben dieses Codes, den sie in jedem Projekt weiterverwenden könnten, bis an ihr Lebensende beschäftigt sind.

    Oder wie es der Volksmund sagen würde: Mit Kanonen auf Spatzen schießen.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    Irgendwann schreiben die Leute nur noch Code, den sie in jedem Projekt weiterverwenden könnten, was jedoch nie geschehen wird, weil sie mit dem Schreiben dieses Codes, den sie in jedem Projekt weiterverwenden könnten, bis an ihr Lebensende beschäftigt sind.
    Andererseits verwenden es die, bei denen es sinnvoll ist, leider viel zu selten. Da kommen dann diese statischen Framework-Monster raus, die man fast komplett neu implementieren muss, nur weil man ein kleines Detail anders haben möchte. Ich bin da mal auf die ersten Swift-Frameworks von Apple gespannt.
    „Meine Komplikation hatte eine Komplikation.“
  • Als Faustregel habe ich: Was ich in ein Framework stecken würde, abstrahiere ich anständig. Was offenkundig in meinem App-Biotop verbleibt, wird genau so weit abstrahiert, wie ich es gerade brauche. (Tatsächlich neige ich aber auch hierbei dazu, zu überabstrahieren. Ich bessere mich aber, weil Christian genau das Gegenteil macht.)

    Ich bin mir ziemlich sicher, dass die Leute, die bei Apple Swift-Frameworks bauen, eher überabstrahieren. Da ist dann Professor "Blowing your Mind" Lead-Engineer. Die Leute werden es toll finden, wie sie C++-Template-Wüsten toll fanden. So richtig techie anstelle von so richtig einfach.

    *Schulterzuck* Solange ich dazu nicht gezwungen werde …
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • markusschalk schrieb:

    Danke @all für eure Antworten!
    Das Bsp. diente nur zur Klarstellung meiner Frage. Ich habe dieses jz noch erweitert. Ich weiß, dass die LogManager Klasse davor keinen Sinn ergeben hat. ;)
    Wiegesagt, war das ja nur ein Codeschnipsel.

    Meine Frage bezog sich darauf, ob dies in Swift so ähnlich wie in C# gelöst wird bzw. ob es gebräuchlich in Swift ist.

    Markus Müller schrieb:

    Aber das bedeutet nicht zwangsläufig, für alles und jedes ein interface zu verwenden.
    Gute Encapsulation und loose coupling habe ich damit schon erreicht und beim Mocking tu ich mir auch leichter.

    Amin Negm-Awad schrieb:

    Wie bei jedem Muster sollte man bedenken, welches Problem es zu lösen gilt und wieso die Leute auf diese Lösung verfallen.
    Das sehe ich auch so... darum auch meine Frage.
    Die Frage ist halt immer, an welcher Stelle Deiner App Du encapsulation und loose coupling brauchst. Immer da, wo es über eine boundary geht (in die Viewschicht, zur DB, IO), bietet sich IoC an. Dann kannst Du auch prima testen. Aber u.U. reichen dafür schon simple datastructures, die über ein konkretes interface (sprich ein normales controller/interactor objekt) weiter gereicht wird.

    Such mal nach clean architecture und Uncle Bob Martin, der bringt das schön auf den Punkt in diversen Keynotes und Blogposts.

    Der Punkt ist allerdings, dass es meistens einfacher ist, die schon vorhandenen Abstraktionen des Frameworks zu verwenden (CoreData, DataSources, KVC), anstatt da das Rad neu zu erfinden.

    Zum Testing: mocking frameworks brauche ich so gut wie nie, auch nicht in objective-c.

    Beste Grüße, Markus
  • Markus Müller schrieb:

    markusschalk schrieb:

    Danke @all für eure Antworten!
    Das Bsp. diente nur zur Klarstellung meiner Frage. Ich habe dieses jz noch erweitert. Ich weiß, dass die LogManager Klasse davor keinen Sinn ergeben hat. ;)
    Wiegesagt, war das ja nur ein Codeschnipsel.

    Meine Frage bezog sich darauf, ob dies in Swift so ähnlich wie in C# gelöst wird bzw. ob es gebräuchlich in Swift ist.

    Markus Müller schrieb:

    Aber das bedeutet nicht zwangsläufig, für alles und jedes ein interface zu verwenden.
    Gute Encapsulation und loose coupling habe ich damit schon erreicht und beim Mocking tu ich mir auch leichter.

    Amin Negm-Awad schrieb:

    Wie bei jedem Muster sollte man bedenken, welches Problem es zu lösen gilt und wieso die Leute auf diese Lösung verfallen.
    Das sehe ich auch so... darum auch meine Frage.
    Die Frage ist halt immer, an welcher Stelle Deiner App Du encapsulation und loose coupling brauchst. Immer da, wo es über eine boundary geht (in die Viewschicht, zur DB, IO), bietet sich IoC an. Dann kannst Du auch prima testen. Aber u.U. reichen dafür schon simple datastructures, die über ein konkretes interface (sprich ein normales controller/interactor objekt) weiter gereicht wird.
    Such mal nach clean architecture und Uncle Bob Martin, der bringt das schön auf den Punkt in diversen Keynotes und Blogposts.

    Der Punkt ist allerdings, dass es meistens einfacher ist, die schon vorhandenen Abstraktionen des Frameworks zu verwenden (CoreData, DataSources, KVC), anstatt da das Rad neu zu erfinden.

    Zum Testing: mocking frameworks brauche ich so gut wie nie, auch nicht in objective-c.

    Beste Grüße, Markus
    danke Markus
    Das wollte ich wissen