2011-12-18 17 views
7

Nel mio tempo libero, sto costruendo un risolutore di Sudoku per cercare di ottenere il blocco di OOP in PHP. Un puzzle di Sudoku, per quelli di voi che non lo conoscono, è nella sua forma più comune una matrice 9x9 di numeri da 1 a 9, con 3x3 quadrati delineati in un modello simile a un tic-tac-toe. Alcuni numeri sono compilati in anticipo. L'obiettivo del puzzle è compilare i numeri rimanenti, in modo che nessuna riga, colonna o quadrato 3x3 contenga lo stesso numero più di una volta.È brutto dichiarare una classe vuota?

Per fare ciò, ho creato un certo numero di classi. Un Cell può essere un elemento di un Constraint, che sono le righe, le colonne e i quadrati 3x3. A Sudoku è una raccolta di Constraint se Cell s. Ho una classe SudokuSolver che include in modo dinamico file di origine con dichiarazioni di classe sottoclasse SolverHelper e crea un'istanza di ciascuna sottoclasse. Un helper ha una funzione Solve() che accetta un argomento come Sudoku. Esamina i Constraint e chiede alle sue celle di eliminare le possibilità di valore in base a ciò che trova. Il programma stesso scorre sugli helper fino a quando nessuno di loro ha dichiarato di essere in grado di eliminare più possibilità.

Ma il fatto che tutte le celle di una riga o di una colonna si allineano, presenta alcuni corollari che vengono sfruttati in alcune tecniche di soluzione. Quindi ho bisogno di distinguere tra righe/colonne e altri Constraint s. Potrei avere le righe e le colonne in diversi array, che non è una cattiva soluzione. Questo ha il vantaggio di consentire una buona opportunità di ottimizzazione: nessuna colonna interseca mai un altro, ad esempio. Potrei anche aggiungere una proprietà booleana IsLinear.

Oppure, e ora arriviamo alla mia domanda: potrei sottoclasse la classe Constraint per avere un LinearConstraint. Ma quella classe sarebbe vuota. Non avrebbe bisogno di sovrascrivere nulla nella classe Constraint. Sarebbe un paio di parentesi graffe, e basta; un oggetto LinearConstraint è speciale in quanto è un'istanza della sua classe. Se volevo o dovevo avere un codice speciale che riguardasse i vincoli lineari, potrei sempre aggiungerlo. La mia domanda è: è il fatto che sto considerando di dichiarare e usare una classe vuota, un segno che sto facendo qualcosa di sbagliato? Sono troppo astratto e teorico su questo?

+0

Sarebbe sufficiente 'nuovo stdClass()'? O '(oggetto) ''' '? –

+0

@JaredFarrish, chiede di estendere una classe esistente senza apportare modifiche (classe figlio vuota) –

+0

Un membro della classe ipotetica avrebbe funzionalità che deriva dalla sua classe base. Quello che voglio dire è che la classe non * aggiungere * nulla alla funzionalità della sua classe base. Non sto affatto pensando di creare un oggetto che non fa nulla. – toon81

risposta

9

Una lezione vuota non è affatto male. Le persone lo usano in vari altri scenari; specialmente nella specializzazione Eccezione.

Non credo che sarà peggio di aggiungere una bandiera nella classe Constraint, per differenziare i due tipi. Preferirei di gran lunga la classe estesa, almeno per motivi di leggibilità del codice.

+0

Mi piace il tuo punto sulle eccezioni! – toon81

+0

Ho lo stesso punto di vista. Una classe vuota può essere utile, solo per rendere il codice più leggibile –

5

Posso essere fraintendere la domanda, quindi portami con me se lo sono! Dal mio punto di vista si desidera avere diversi tipi di classi Constriant in modo che la funzione Solve() agisca diversamente a seconda del tipo di griglia? (Per ragioni di ottimizzazione, presumibilmente).

Estendere la classe Constraint in questo modo sarebbe sicuramente un modo per distinguere i tipi e non penso sia una pratica particolarmente negativa.

Si può tuttavia desiderare di avere in futuro ancora più tipi diversi di Constraint (non so, dire che sei impazzito e hai deciso di fare 3D sudoku o qualcosa del genere). In questo caso potrebbe essere meglio trasformare la classe originale Constraint in una abstract class ed estenderla. È possibile impostare come sempre molti sottosquadri che si desidera e tutti avranno la stessa funzionalità (più eventuali funzioni aggiunte esclusive di tale vincolo).

In questo modo è possibile impostare la sottoclasse vuota LinearConstraint e non doversi preoccupare di mescolare di nuovo tutto quando si decide di avere ancora più sottoclassi Constraint.

+0

Penso che tu abbia capito bene cosa volevo chiedere, cosa ho intenzione di fare, finire il programma e poi provare a implementare la soluzione Killer Sudoku. Sudoku, eccetto che non viene fornito con nessun numero inserito. Invece, ci sono aree con linee tratteggiate intorno a loro e un numero, e i numeri all'interno di quelle aree devono sommarsi a quel numero. Quindi, per esempio, se hai un'area 2x1 che aggiunge fino a 3, deve essere un 2 e un 1. Questo, ovviamente, sarebbe un modo eccellente di testare le mie abilità OOP e certamente permetterebbe l'interessante sottoclasse di 'Constraint'. – toon81

Problemi correlati