2010-12-01 2 views
0

Ich versuche ein Pokerspiel in ein korrektes OOP-Modell zu übersetzen.
Die Grundlagen:Wie zu vermeiden, eine generische Klasse mit Attributen "füllen"?

class Hand 
{ 
    Card cards[]; 
} 
class Game 
{ 
    Hand hands[]; 
} 

ich Spiele und Hände aus einer Textdatei. Ich analysieren, um die Textdatei mehrmals, aus mehreren Gründen:

  • get somes Infos (Grund 1)
  • einige Statistiken berechnen (Grund 2)
  • ...

Für Grund 1 Ich brauche einige Attribute (a1, b1) in der Klasse Hand. Für Grund 2 brauche ich einige andere Attribute (a2, b2). Ich denke der schmutzige Weg wäre:

Ich würde bedeuten, dass einige Attribute die meiste Zeit nutzlos sind. Also, sauberer zu sein, könnten wir tun:

class Hand 
{ 
    Card cards[]; 
} 
class HandForReason1 extends Hand 
{ 
    Int a1,b1; 
} 

Aber ich fühle mich wie ein Hammer ...

Meine Frage ist: Gibt es eine Zwischen Art und Weise? Oder die Hammerlösung ist die gute? (In diesem Fall, was wäre eine korrekte Semantik?)

PS: Entwurfsmuster willkommen :-)
PS2: Strategie-Muster ist der Hammer, nicht wahr?

* EDIT * Hier ist eine Anwendung:

// Parse the file, read game infos (reason 1) 
// Hand.a2 is not needed here ! 
class Parser_Infos 
{ 
    Game game; 
    function Parse() 
    { 
      game.hands[0].a1 = ... 
    } 
} 
// Later, parse the file and get some statistics (reason 2) 
// Hand.a1 is not needed here ! 
class Parser_Stats 
{ 
    Game game; 
    function Parse() 
    { 
     game.hand[0].a2 = ... 
    } 
} 
+0

Während die Formatierung Ihrer Post mit html mehr oder weniger funktioniert, wird es einfacher und schneller, die von Stack Overflow bereitgestellte Markdown-Engine zu verwenden. [Hilfeseite bearbeiten] (http://stackoverflow.com/editing-help). – dmckee

+0

Ich denke, es wird für uns viel einfacher sein, Ihr Problem zu erfassen, wenn Sie ein Beispiel aus dem wirklichen Leben für Ihre "Attribute" verwenden. Was bedeuten a1 und b1, a2 und b2 genau? – Fortega

Antwort

0

eine Kette von Verantwortung Mit einer Poker-Hand zu erkennen, was ich tun würde. Da jede Hand ihre eigenen Eigenschaften hat, kann man nicht nur eine generische Hand haben.

So etwas wie

abstract class Hand { 
    protected Hand next; 

    abstract protected boolean recognizeImpl(Card cards[]); 

    public Hand setNext(Hand next) { 
     this.next = next; 
     return next; 
    } 

    public boolean Hand recognize(Card cards[]) { 
     boolean result = ; 
     if (recognizeImpl(cards)) { 
     return this; 
     } else if (next != null) { 
     return next.recognize(cards); 
     } else { 
     return null; 
     } 
    } 
} 

Und dann Ihre Implementierung haben

class FullHouse extends Hand { 
    protected boolean recognizeImpl(Card cards[]) { 
     //... 
    } 
} 
class Triplet extends Hand { 
    protected boolean recognizeImpl(Card cards[]) { 
     //... 
    } 
} 

Dann Ihre Kette

// chain start with "best" hand first, we want the best hand 
// to be treated first, least hand last 
Hand handChain = new FullHouse(); 
handChain 
    .setNext(new Triplet()) 
    //.setNext(...)  /* chain method */ 
; 

//... 

Hand bestHand = handChain.recognize(cards); 
if (bestHand != null) { 
    // The given cards correspond best to bestHand 
} 

auch bauen, mit jeder Hand eine eigene Klasse ist, können Sie initialisieren und haben dann halte und berechne ganz bestimmte Dinge. Aber da Sie Hand Klassen so viel wie möglich manipulieren sollten (um so viel OO wie möglich zu behalten), sollten Sie vermeiden, Ihre Hände auf eine bestimmte Handklasse zu legen.

** UPDATE **

In Ordnung, so Ihre ursprüngliche Frage zu beantworten (sig) die Klasse Hand ist für die Manipulation und Behandlung "Hände".Wenn Sie andere Statistiken oder andere Anforderungen berechnen müssen, ist das Umbrechen Ihrer Klasse Hand möglicherweise keine gute Idee, da Sie eine zusammengesetzte Klasse erhalten werden, was nicht wünschenswert ist (aus Gründen der Wartungsfreundlichkeit und des OOP-Paradigmas).

Aus dem Grund 1, es ist in Ordnung, verschiedene Arten von Händen zu haben, wie die Kette der Verantwortung veranschaulichen; Sie können Ihre Datei lesen, verschiedene Arten von Händen mit den vielen Parametern erstellen, wie es erforderlich ist.

Aus Grund 2 könnten Sie andere Lösungen betrachten. Eine wäre, Ihre Hand Klassen Feuer Ereignisse (zB: wenn es erkannt wird) und Ihre Anwendung könnte diese Hände in eine andere Klasse registrieren, um auf Ereignisse zu hören. Diese andere Klasse sollte auch dafür verantwortlich sein, die notwendigen Daten aus den Dateien zu sammeln, die Sie gerade lesen. Da eine Hand nicht dafür verantwortlich ist (oder nicht sein sollte), statistische Daten zu sammeln, ist die Quintessenz, dass Sie etwas anderes handhaben müssen.

Ein Paket = kohärente API und Funktionalitäten

Eine Klasse = kohärente Funktionalitäten (eine Hand ist eine Hand, keine statistische Container)

Eine Methode = a (single) Funktionalität (Wenn eine Methode mehr als eine Funktionalität verarbeiten muss, brechen Sie diese Funktionalitäten in separate private Methoden auf und rufen Sie sie von der öffentlichen Methode ab)

Ich bin giv Sie eine generische Antwort hier, weil Grund 1 und Grund 2 sind nicht spezifisch.

+0

Danke für deine Antwort ... Aber vielleicht war ich nicht klar, denn das war nicht meine Frage :-) Ich versuche nicht, eine Pokerhand zu erkennen, ich versuche den besten Weg zu finden, Attribute zu "verteilen" Klassen. Einige Attribute in der Klasse Hand werden zum Berechnen von Statistiken benötigt. Andere Attribute werden für andere Dinge benötigt ... Ich schätze, dass es ziemlich dreckig ist, alle Attribute in eine Handklasse zu schreiben. Aber Vererbung scheint ein bisschen "schwer". Aber das könnte der einzige Weg sein ... Oder gibt es eine andere Möglichkeit, ein Modell zu erstellen? – Antoine

+0

@Antoine meine Antwort war auch nicht zu klar. Lesen Sie die Bearbeitung für mehr Präzision. –

+0

Ich bin immer noch ein bisschen verloren, aber du hast mir Hinweise und Regeln gegeben. Ich bin ein sehr prozeduraler Programmierer (alte Schule) und manchmal finde ich es schwierig, Objekte überall zu modellieren :-) – Antoine

Verwandte Themen