OOP, abgeleitete Klassen

  • VB.NET
  • .NET 4.5

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von SpaceyX.

    OOP, abgeleitete Klassen

    Hallo zusammen,

    ich lese schon seit einiger Zeit in diesem Forum mit und konnte mir dank eurer Beiträge schon sehr viel selbst beibringen. Dafür schon einmal ein Danke!

    Ich habe vor einiger Zeit nun meinen Horizont von VBA/Excel auf VB.NET erweitert. Mein erstes und derzeitiges Hauptprojekt soll ein Preis-Kalkulationsprogramm werden.
    Das Programm an sich steht auch schon seit einiger Zeit (nicht ganz fertig, aber benutzbar :D ), allerdings ohne wirkliche OOP.
    Das führt mittlerweile aber leider bei Erweiterungen/ Veränderungen des Programms zu immer mehr Krücken und Verwirrung, weil ich den Überblick verliere.
    Damit kommen wir zum Problem und hoffentlich auch der Lösung: Einarbeitung in die OOP.


    Zunächst einmal zum Verständnis die Idee / das Konzept hinter dem Projekt:

    Ist-Stand ohne OOP: Man gibt alle Parameter an, die das Produkt haben soll und muss auch die Fertigungsart (Maschinen) auswählen. Das Ergebnis sind dann u.a. die Herstellkosten.
    Im "Main"-Form sind teilweise sehr lange Funktionen / Subs, welche mit "If / Then bzw. "Select Case" die Eigenschaften etc. der angegebenen Fertigungsart und Maschine auslesen und die Produktionskosten daraufhin ermitteln.

    Problem:
    Die Anwender kennen nicht unbedingt die beste Fertigungsart, da diese sich teilweise nur in kleinen Details unterscheiden.

    Wunsch: Man gibt alle Parameter an und das Programm ermittelt die funktionierende(n) bzw. die günstigste Fertigungsart.



    Vereinfachtes Beispiel (die Sinnhaftigkeit sei mal dahingestellt):

    Ich möchte einen Würfel herstellen.
    • Eigenschaften: 6 Seiten, weiß, Kunststoff, Größe S

    • Fertigungsart1: Kann bis 6 Seiten, kann weiß, kann Kunststoff & Holz, bis Größe S
    • Fertigungsart2: Kann bis 20 Seiten, kann weiß, kann nur Holz, bis Größe L
    • Fertigungsart3: Kann bis 8 Seiten, kann alle Farben, kann nur Kunststoff, bis Größe M
    Ergebnis:
    • Fertigungsart1 und Fertigungsart3 würden in Frage kommen
    • Fertigungsart2 funktioniert aufgrund des Materials nicht.

    Die Produktionskette ist natürlich in der Realität noch wesentlich länger und tiefer, aber die folgenden Schritte würden dann ja äquivalent aufgebaut werden.
    Für die Zukunft wäre auch noch ein Wunsch, gewisse Entscheidungen vom Benutzer "überschreiben" zu lassen. So wie ich das bisher verstanden habe kann man dafür in abgeleiteten Klassen "Override" nutzen. Oder doch lieber ein einfaches "If Then Else"?




    Ich könnte mit meinem Wissensstand jetzt die Basisklasse "Würfel" erstellen, welche u.a. die Eigenschaften "Anzahl Seiten", "Farbe", "Material" und "Größe" beinhaltet.
    Aus dieser Klasse würde ich dann mit einem Konstruktor "Public Sub New(Parameter)", anhand der Eingaben im Main-Form, ein neues Objekt erstellen. So weit so gut.

    Was ist nun der sinnvollste Weg, die Einschränkungen der Fertigungsarten abzufragen und am Ende die "funktionierende(n)" Fertigungsart(en) zu ermitteln?
    1. Methoden in der Klasse "Würfel" erstellen, welche dann mit "If Then" oder "Select Case" versuchen die einzelnen Kriterien abzuarbeiten? So habe ich es momentan ja schon in meinem Programm, nur eben ohne die Klasse, sondern mit Public Variablen.
      Das ist aber, wie erwähnt, mittlerweile relativ unübersichtlich geworden.
    2. (Abgeleitete) Klassen für jede Fertigungsart erstellen, die mit den Werten aus dem erstellen Objekt gefüttert werden und dann am Ende z.B. eine eigene Property "Funktioniert" mit "True" oder "False" füllen?
    3. Eine ganz andere Vorgehensweise?

    Ich hoffe ihr versteht was ich meine und könnt mir ein paar Denkanstöße geben ?(

    Gruß Erik
    Hey,

    für die Produktionsarten brauchst Du keine Vererbung, außer ich habe Dein Problem falsch verstanden. Bilde auch jede Produktionsart in einer Klasse ab.

    VB.NET-Quellcode

    1. Public Class ProductionType
    2. Public Property MaxSides As Integer
    3. Public Property Colors As New List(Of Color)
    4. Public Property Materials As New List(Of Materials)
    5. Public Property MaxSize As Sizes
    6. Public Sub New(maxSides As Integer, colors As Color(), materials As Materials(), maxSize As Sizes)
    7. Me.MaxSides = maxSides
    8. Me.Colors.AddRange(colors)
    9. Me.Materials.AddRange(materials)
    10. Me.MaxSize = maxSize
    11. End Sub
    12. End Class


    Weiterhin legst Du für die Materialen und Großen jeweils ein ENUM an. Sollte es mit den Großen und Materialen tiefer gehen, kann man auch diese als Klasse abbilden.

    VB.NET-Quellcode

    1. Public Enum Materials
    2. Plastic = 0
    3. Wood = 1
    4. End Enum
    5. Public Enum Sizes
    6. S = 0
    7. M = 1
    8. L = 2
    9. XL = 3
    10. End Enum


    Zu Beginn Deines Programms definierst Du die verschiedenen Arten der Produktion.

    VB.NET-Quellcode

    1. Module Module1
    2. Private _productionTypes As New List(Of ProductionType)
    3. Sub Main()
    4. _productionTypes.Add(New ProductionType(6, {Color.White}, {Materials.Wood, Materials.Plastic}, Sizes.S))
    5. _productionTypes.Add(New ProductionType(20, {Color.White}, {Materials.Wood}, Sizes.L))
    6. _productionTypes.Add(New ProductionType(8, {Color.White, Color.Green, Color.Red}, {Materials.Plastic}, Sizes.M))
    7. Dim dice As New Form(6, Color.White, Materials.Plastic, Sizes.M, _productionTypes)
    8. End Sub
    9. End Module


    Ein Produktionstyp übernimmt die maximale Anzahl der Seiten, ein Array von Farben, welche dieser Typ fertigen kann, die möglichen Materialen und die maximale Größe. Als nächstes erstellst Du Dir Deine gewünschte Würfel-Instanz. Der Würfel, bzw. die Form wird als Klasse abgebildet.

    VB.NET-Quellcode

    1. Public Class Form
    2. Public Property Sides As Integer
    3. Public Property Color As Color
    4. Public Property Material As Materials
    5. Public Property Size As Sizes
    6. Public Property TypesProduction As New List(Of ProductionType)
    7. Public Sub New(sides As Integer, color As Color, material As Materials, size As Sizes, productionTypes As List(Of ProductionType))
    8. Me.Sides = sides
    9. Me.Color = color
    10. Me.Material = material
    11. Me.Size = size
    12. GetProductionType(productionTypes)
    13. End Sub
    14. Private Sub GetProductionType(productionTypes As List(Of ProductionType))
    15. For Each x As ProductionType In productionTypes
    16. If Me.Sides > x.MaxSides Then Continue For
    17. If Not x.Colors.Contains(Me.Color) Then Continue For
    18. If Not x.Materials.Contains(Me.Material) Then Continue For
    19. If Me.Size > x.MaxSize Then Continue For
    20. Me.TypesProduction.Add(x)
    21. Next
    22. End Sub
    23. End Class


    Die Klasse übernimmt die Anzahl der Seiten, die Farbe, das Material, die Größe. Ebenfalls muss der Klasse mitgeteilt werden, welche Arten der Produktion es gibt. Hier als productionTypes As List(Of ProductionType), welche beim Programmstart festgelegt wurde.

    Am Ende des Konstruktors werden die möglichen Produktionstypen ermittelt und in der Property TypesProduction gespeichert. In dieser Routine gehst Du jeden vorhandenen Produktionstypen durch und prüfst, ob die Anzahl der Seiten überschritten wurde, ob der Produktionstyp die Farbe beinhaltet, ob der Produktionstyp das Material beinhaltet und ob die Größe überschritten wurde. Übersteht ein Produktionstyp diesen Test, so wird er in der Property gespeichert, wenn nicht wird er übersprungen.

    Ich würde das in Etwa so machen. Gibt natürlich mehrere Wege, wie so oft.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    How to turn OPTION STRICT ON
    Why OPTION STRICT ON
    Hey SpaceyX!
    Danke erstmal für die superschnelle Antwort.

    Im Grunde hast du mich schon richtig verstanden. Ich bin nur bisher immer davon ausgegangen, der Weg sei, die Klasse des Würfels in die der Produktionsarten einzuarbeiten und nicht umgekehrt.
    Ich konnte deinem Beispiel größtenteils folgen. Ich bin auch ein wenig verblüfft, da ich diese Art und Weise von alleine wahrscheinlich niemals erarbeitet hätte, sie mir vom Stil aber schon sehr gefällt.
    Leider kann ich erst Montag wieder auf das Projekt zugreifen. Bis dahin werde ich mir noch Gedanken über die Länge der Produktionskette machen bzw. wie ich diese nach deinem Beispiel bei mir abbilden könnte.
    Für meine Produkte gibt es noch diverse Weiterverarbeitungen auf weiteren Maschinen, die natürlich ebenfalls gewisse Bedingungen mitbringen.

    Gerne kannst du dir dazu auch Gedanken machen, ich versuche jedoch erstmal mich meiner eigenen grauen Zellen zu bedienen! :D
    Meine Idee dazu bisher:
    • Ebenfalls Public Properties z.B as boolean in Form einfügen, welche speichern, ob eine gewisse Weiterverarbeitung gewünscht ist oder nicht.
    • Diese dann mit If Then abfragen und bei True äquivalent zu GetProductionType() abfragen, welche der vorhandenen Maschinen (in Abhängigkeit von Stückzahl, Größe etc.) für die gewünschte Weiterverarbeitung am besten geeignet ist.
    ODER (was mir stilistisch glaube ich besser gefällt):
    • Direkt eine List(of Weiterverarbeitung) anlegen, (äquivalent zu Material und Farbe), die alle vom Benutzer angegebenen Weiterverarbeitungen beinhaltet. Hier weiß ich nur noch nicht ganz, wie ich von dort aus weitergehe.

    Dir und allen Mitlesern ein schönes Wochenende! ^^
    Versuche, Probleme getrennt zu betrachten. Beispielsweise kannst Du alle Deine Maschinen, samt Ihren Eigenschaften, als Klasse abbilden. Weiterhin kannst Du alle Produktionsschritte als Klasse abbilden und diese dann miteinander in Beziehung setzen. Vererbung macht z. B. bei Maschinen oder den verschiedenen Produkten Sinn. Melde Dich wieder, wenn Du nicht weiter kommst, bzw. konkrete Daten zu dem Problem hast.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    How to turn OPTION STRICT ON
    Why OPTION STRICT ON