Ich bekomme den "MindSet" Objekt-Orientierung nicht hin -- am liebsten würde ich Module benutzen um Ordnung zu schaffen

  • VB.NET
  • .NET 4.5

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Dksksm.

    Ich bekomme den "MindSet" Objekt-Orientierung nicht hin -- am liebsten würde ich Module benutzen um Ordnung zu schaffen

    Moin Leute,

    ich schaff es immer wieder, dass mein Code in "Form1" zu chaotisch aussieht. Hier ein Select Case dort eine Ansammlung von Button1.click und so weiter.
    Mein Gehirn sagt füg ein Modul hinzu und lager das Zeug aus.

    Ich weiß, dass ich statt dessen Klassen benutzen soll, irgendwie komm ich in das Denken nicht rein.


    Konkret bin ich dabei einen Audio-Equalizer mit Bass.dll zu erzeugen und diesen über einen Drehpoti am Arduino zu steuern.
    Da kommt alles in "Form1" zusammen:

    file dialoge (.mp3 Datei auswählen)
    Bass.dll Inizalisierung
    Port Scan für Serial Com
    etc.

    Wie lerne ich das besser zu sortieren. Wie habt Ihr das gelernt? In meinen Klassen wird irgendwie immer alles Public deklariert und diese ganzen Button1.click Subs verschwinden auch nicht.

    z.B. mal einige Code Blöcke die bei mir in "Form1" stehen
    Spoiler anzeigen

    VB.NET-Quellcode

    1. 'einfach ein paar Zeilen (nicht vollständig)
    2. Dim SoundFilePath_1 As String = "1.mp3"
    3. Public fcenter0 As Integer = 310
    4. Public fcenter1 As Integer = 850
    5. Public fcenter2 As Integer = 1500
    6. Private Sub BtFile1_Click(sender As Object, e As EventArgs) Handles BtFile1.Click
    7. Using openFileDialog1 As New OpenFileDialog()
    8. openFileDialog1.InitialDirectory = ""
    9. openFileDialog1.Filter = "Mp3 Dateien (*.mp3)|*.mp3|alle Dateien (*.*)|*.*"
    10. If openFileDialog1.ShowDialog() = DialogResult.OK Then
    11. SoundFilePath_1 = openFileDialog1.FileName
    12. End If
    13. End Using
    14. TxbFile1.Text = SoundFilePath_1
    15. 'Process.Start(Pfad1) ' wuerde mp3 player windows mit dem pfad oeffnen
    16. End Sub
    17. Private Sub TrkVol2_Scroll(sender As Object, e As EventArgs) Handles TrkVol2.Scroll
    18. 'Abfangen wenn keine Datei spielt
    19. Dim VolumeSlider2 As Single
    20. VolumeSlider2 = Convert.ToSingle(TrkVol2.Value / 100)
    21. Bass.BASS_ChannelSetAttribute(chan2, BASSAttribute.BASS_ATTRIB_VOL, VolumeSlider2)
    22. End Sub
    23. Private Sub TrackBar_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TrackBar1.Scroll, TrackBar2.Scroll, TrackBar3.Scroll, TrackBar4.Scroll, TrackBar5.Scroll, TrackBar6.Scroll
    24. SetParametersEQ(fx(0), fcenter0, TrackBar1.Value - 7) 'effect, Centerfrequency, Gain
    25. SetParametersEQ(fx(1), fcenter1, TrackBar2.Value - 7) 'fcenter(0...n)
    26. SetParametersEQ(fx(2), fcenter2, TrackBar3.Value - 7) 'fcenter(0...n)
    27. SetParametersEQ(fx(3), fcenter3, TrackBar4.Value - 7) 'fcenter(0...n)
    28. SetParametersEQ(fx(4), fcenter4, TrackBar5.Value - 7) 'fcenter(0...n)
    29. SetParametersEQ(fx(5), fcenter5, TrackBar6.Value - 7) 'fcenter(0...n)
    30. End Sub
    31. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    32. Me.CenterToParent()
    33. BtnCon.Enabled = False
    34. BtnCon.BringToFront()
    35. BtnDiscon.Enabled = False
    36. BtnDiscon.SendToBack()
    37. CmbBaud.SelectedItem = "9600"
    38. 'serial end
    39. If IO.File.Exists(SoundFilePath_1) Then
    40. TxbFile1.Text = SoundFilePath_1
    41. End If
    42. If IO.File.Exists(SoundFilePath_2) Then
    43. TxbFile2.Text = SoundFilePath_2
    44. End If
    45. Bass.BASS_SetConfig(BASSConfig.BASS_CONFIG_GVOL_STREAM, TrkGvol.Value)
    46. 'Label für EQ setzen
    47. LbEq1.Text = Convert.ToString(fcenter0) & " Hz"
    48. LbEq2.Text = Convert.ToString(fcenter1) & " Hz"
    49. LbEq3.Text = Convert.ToString(fcenter2) & " Hz"
    50. LbEq4.Text = Convert.ToString(fcenter3) & " Hz"
    51. LbEq5.Text = Convert.ToString(fcenter4) & " Hz"
    52. LbEq6.Text = Convert.ToString(fcenter5) & " Hz"
    53. End Sub
    54. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    55. Try
    56. Dim lastValue, temp As Integer
    57. Dim i As Single = CSng(SerialPort1.ReadExisting)
    58. 'LblPotentiometer.Text = "Potentiometer Value : " & i.ToString
    59. If lastValue <> CInt(i) Then
    60. lastValue = CInt(i)
    61. temp = CInt(lastValue / 2.55)
    62. LblPotentiometer.Text = "Potentiometer Value : " & temp
    63. TrkVol1.Value = temp
    64. 'siehe TrkVol1_ValueChanged ca 10 zeilen tiefer
    65. End If
    66. Catch ex As Exception
    67. 'stays empty if one attamp fails dont worry the next will be okay
    68. End Try
    69. End Sub
    Das einfachste wäre als Übung: Allen Arbeitscode in eine einzige Klasse zu hauen, der nix mit dem GUI zu tun hat. Und GUI-Subs delegieren nur an diese Klasse, also z.B.

    VB.NET-Quellcode

    1. Private Sub TrkVol2_Scroll(sender As Object, e As EventArgs) Handles TrkVol2.Scroll
    2. DeineKlasseninstanz.SetVolume(TrkVol2.Value / 100)
    3. End Sub

    Dadurch wird der Form1*-Code entschlankt. Klar, dadurch stopfst Du Dir die Klassendatei voll. Aber Du lernst auch, die Daten weiterzugeben. Stell Dir vor, Du ersetzt irgendwann ein CE, z.B. Deinen Lautstärken-Slider, durch einen hypermodernen Dreh-Button. Dann müsstest Du mit Deinem Code viele Stellen ändern. Mit der Klasse hingegen fasst Du nur die Formularklasse an, während Deine andere Klasse unangetastet bleibt. Dann geht es aber weiter mit bidirektionaler Kommunikation, also dass Deine Klasse dem Formular was sagen will. Dann bist Du bei Events. Später solltest Du merken, dass Deine Klasse ganz viele Aufgaben hat, obwohl jede nur eine haben sollte. Also musst Du sie aufteilen. Und am Ende erhältst Du viele kleine Klassen, die ziemlich unabhängig voneinander entwickelt werden können. Dann sind wir fast schon bei OOP.

    *bitte besseren Namen wählen!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    einfach Code planlos von einer Datei in eine andere verlegen ist nur eine Verschlimmerung.
    Aber ich könnte mir vorstellen, den Equalizer iwie als UserControl zu gestalten, mit einigen Schiebern und Schnickschnack.
    Dann geht da ganz viel Code hinein, der eben mit Sound zu tun hat, und was man da einstellt, und was man da anzeigt.
    Dadurch wird das Form freier für anderweitigen Code.
    Man kann auch noch weiter denken, etwa ein MusicPlayer-UserControl, und darauf wiederum das Equalizer-UserControl - sowas.
    Dass Du Dir das vorstellen kannst, denke ich mir. Aber der TE hat offensichtlich momentan noch keine Vorstellung von Klassen und wie man die nutzt. Mag sein, dass mein Vorschlag planlos erscheint, aber 5 Gedankensprünge aus Sicht des TEs zu machen, sehe ich ebenfalls momentan nicht als zielführend.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Danke @ EdR und VaporiZed für euren Input! Ich bin etwas frustriert, da ich schon seit Monaten versuche Klassen/Objekten zu benutzen. Leider geht es nicht wirklich voran. Wie schon geschrieben habe ich Schwierigkeiten das "zu sehen" wo eine Klasse sinn macht und was da rein gehört.
    Ich hoffe wirklich, dass sich das mit der Zeit bessert.

    Ich mach es mal so wie VaporiZed vorschlägt einfach Kassen erzeugen, auch wenn die nicht die besten sind und hoffen das es mit der Zeit effizienter wird.

    @EdR hab eben mal bei YouTube nach UserControls geschaut -> kann ich mir das gedanklich so wie ein "Form2" als integriertes Feld in einer "Form1" vorstellen?
    @nogood Trenne Daten und GUI.
    Mach Dir nen Wrapper um die Bass.DLL-Funktionalität.
    Stell Dir einfach vor, es gäbe eine andere DLL mit einer der Bass.dll äquivalenten Funktionalität, die Du ebenfalls ansteuern möchtest.

    Quellcode

    1. Hintergrund:
    2. Mehrere Kameras verschiedener Hersteller in einem einheitlichen Layout und demselben Wrapper ansteuern.
    3. Allerdings gibt es da für jede Kamera eine separate DLL.
    Mach Dir nen UserControl für diesen Wrapper.
    Dieses UserControl ziehst Du auf Deine GUI und feddich.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!

    nogood schrieb:

    @EdR hab eben mal bei YouTube nach UserControls geschaut -> kann ich mir das gedanklich so wie ein "Form2" als integriertes Feld in einer "Form1" vorstellen?
    Uih - Utube ist meist ein schlechter Ratgeber.
    Ansonsten stellst du dir das glaub richtig vor (Glück gehabt).

    Du brauchst aber nicht Utube gucken, sondern probiers einfach aus: Menü Projekt - UserControl hinzufügen.
    Da bastelste dann ein paar Controls drauf, Textboxen, Listboxen,... , und speichern.
    Dann ein neues Form hinzufügen, und dann kannste dein UserControl auch schon aus der Toolbox da draufziehen, und siehst, wie das gemeint ist.

    Soweit zur Spielwiese.

    Wenn du wirklich ein UserControl entwickelst, dann achte von vornherein auf die Benamung: Wenn ich später von dir Code sehe, mit UserControl1 werd ich pampig <X