Wie wandle ich diese prozedurale Programmierung in objektorientierte Programmierung um?

7

Ich habe einen Quellcode, der konvertiert werden muss, indem Klassen, Objekte und Methoden erstellt werden. Bis jetzt habe ich nur das ursprüngliche main in eine separate Klasse umgewandelt. Aber ich weiß nicht, was ich mit Konstruktor machen soll und welche Variablen privat sein sollen. Dies ist der Code:

%Vor%

Die Hauptklasse ist:

%Vor%

Soll ich die Card-Klasse vereinfachen, indem ich andere Klassen erstelle?

Durch diesen Code hat mein Javadoc keinen Konstruktor. Also brauche ich Hilfe dabei!

    
keitamike 18.03.2010, 13:19
quelle

6 Antworten

11
  

Aber ich weiß nicht, was ich mit Konstruktor machen soll und welche Variablen privat sein sollen.

Was auch immer sein kann, sollte private sein. Um das zu bestimmen, ist es oft am einfachsten, alles private zu markieren und dann, wenn du einen "pain point" triffst, es auf public zu promoten.

Für welche Klassen Sie brauchen, sehen Sie sich den vorhandenen Code für "Gerüche" wie:

an %Vor%

Sie haben dort ein "benanntes Primitiv" - und es wird ziemlich oft benutzt. Dies macht es zu einem wichtigen Nomen für Ihr Programm. Verkapseln Sie es in eine Klasse:

%Vor%

Suchen Sie nun, wo Sie dieses benannte Primitiv manipulieren:

%Vor%

Das sind Hauptziele für Methoden:

%Vor%

Und dann - schauen Sie sich einfache Verallgemeinerungsmöglichkeiten an. Cards ist derzeit auf einer 4 x 4-Karte fest programmiert - lasst uns das parametrieren:

%Vor%

Jetzt brauchen wir jemanden, der length und width zur Verfügung stellt - das sind Konstruktoren für:

%Vor%

Und dann erkennen wir, dass Cards kein so guter Name dafür ist ... Es ist eher ein Board - benenne es um und gehe zum nächsten "named primitive" oder smell 2 .

1 Ich benutze "named primitive", um denselben primitiven Typ anzugeben, der entweder global ist oder zwischen Methoden mit demselben Namen weitergegeben wird. Da es keine Klasse gibt, ist die semantische Bedeutung rein im Namen - oft ist dieser Name ein guter Ausgangspunkt für eine Klasse. Es ist verwandt mit dem bekannten "primitiven Obsession" -Codegeruch, aber etwas anders, da es keine große Anzahl primitiver Typen erfordert, die sich als Klasse tarnen. Ein einzelnes benanntes Primitiv kann zu einer Klasse hochgestuft werden.

2 Viele Code-Gerüche sind speziell für OOP-Code. Wenn Sie prozeduralen Code betrachten, den Sie in OO zu konvertieren versuchen, sind "primitive Obsession", "Datencluster", "Nachrichtenketten" und "lange Parameterlisten" am relevantesten.

    
Mark Brackett 18.03.2010, 14:30
quelle
8

Es sieht aus wie das klassische Memory-Spiel mit Karten. Ich sehe vier Hauptklassen:

  1. Spiel
  2. Deck
  3. Karte
  4. Gitter

Hier sind einige Vorschläge für Eigenschaften und Methoden für jeden. Es ist unvollständig, aber es sollte dich in Schwung bringen.

%Vor%     
Marcus Adams 18.03.2010 13:40
quelle
3

Bevor Sie sich über Objekte Gedanken machen, sollten Sie die Abschnitte zuerst in benannte Methoden trennen, damit Sie besser verstehen, was die einzelnen Teile tun. Das ist wichtig, ob es nun OO ist oder nicht. Zum Beispiel:

%Vor%

sieht so aus, als würde es das Board ausdrucken. Machen Sie das zu einer separaten Funktion und nennen Sie es printBoard oder etwas ähnliches.

Was Klassen betrifft, würde ich wahrscheinlich eine Board-Klasse erstellen, die Ihre cards und cardstatus und Methoden hat, um eine aktuelle Karte zu überprüfen, wahrscheinlich shuffle . Nachdem Sie das erledigt haben, würde ich versuchen, alle Ein- und Ausgaben aus der Board-Klasse zu entfernen.

Das Refactoring ist selten ein einstufiger Prozess. Das Rewriting ist eine Option, da es sich um ein relativ kleines Programm handelt, aber Sie werden wahrscheinlich einige der zuvor behobenen Bugs und wahrscheinlich einige neue Bugs wieder einführen (dasselbe gilt für das Refactoring, kleinere Änderungen machen es jedoch etwas weniger wahrscheinlich) / p>     

Davy8 18.03.2010 13:59
quelle
1

Diese Antwort veranschaulicht ein mögliches Refactoring, das Sie tun können, um Ihren Ansatz objektorientierter zu machen. Es behandelt nicht die Problemdomäne (Karten, Decks usw.), die von anderen Antworten angesprochen werden. Stattdessen wird beschrieben, wie Sie OO-Prinzipien verwenden können, um die programmatische Implementierung in einer mehr OO-Art zu bewältigen.

Der erste Schritt, den ich machen würde, ist das Herausrechnen des so genannten PrompedLoop-Konstrukts. Sie haben eine do / while-Schleife in .play, die den Benutzer auffordert, ob er rennen soll oder nicht, und während er ja sagt, führt er eine Aktion durch.

Nehmen Sie diese Funktionalität und kapseln Sie sie ein. Machen Sie die Karte zu einem ausführbaren Objekt und erlauben Sie einem PrompedLoop, es wiederholt auszuführen.

%Vor%

Dann kann .play nur eine einzelne Instanz einer Spielaktion sein und muss die Schleifenfunktionalität nicht integrieren. Sie haben dann die Möglichkeit, den PromptedLoop für andere Programme erneut zu verwenden, und Sie können .play leichter lesen, da Sie nicht durch die Tatsache abgelenkt werden, dass es möglicherweise durchgeschleift wird.

    
Jason R. Coombs 18.03.2010 13:43
quelle
0

Leider ist die beste (einzige) Möglichkeit, ein "prozedurales" Programm in "OO" umzuwandeln, es von Grund auf neu zu erstellen.

Entwerfen Sie Ihr Objektmodell und die Funktionalität, von der Sie denken, dass jedes Objekt sie haben sollte, und schreiben Sie die Klassen und Methoden-Stubs.

Dann können Sie möglicherweise zu Ihrem ursprünglichen Code zurückkehren und einige dieser Funktionen aus den Prozeduren und in die Objekte ziehen.

    
Robin Day 18.03.2010 13:25
quelle
0

In diesem Code finden Sie alle Arten von Gerüchen . Wenn du wirklich schönen Code daraus machen willst, der Fowlers Refactoring Kapitel für Kapitel liest und alle gewonnenen Kenntnisse sofort anwendet.

Ein anderer Ansatz ist einfach, es nicht zu berühren, "nicht funktionierende Maschine reparieren".

    
Roman 18.03.2010 13:28
quelle

Tags und Links