2009-03-10 11 views
5

Sto scrivendo un'API per la creazione di forme geometriche e sto incontrando alcune difficoltà nel nominare i miei metodi.Ho bisogno di consigli per la denominazione dei metodi wordy

Prendiamo un caso semplice: creazione di un cerchio. Molti di noi potrebbero avere familiarità con un metodo come graphics.drawEllipse(x, y, w, h). Per disegnare un cerchio, devi conoscere la coordinata in alto a sinistra, la larghezza e l'altezza del cerchio.

La mia API ha lo scopo di facilitare lo sviluppo di forme da parte di uno sviluppatore utilizzando una varietà di informazioni, senza eseguire molti calcoli matematici, cosa banale per le cerchie, ma più complicata per altre forme. Ad esempio, dovresti anche essere in grado di disegnare un cerchio in base alle coordinate e al raggio del centro o alle coordinate in alto a sinistra e in basso a destra.

Così Ho una classe Circle con metodi di fabbrica come:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

Mi sento come se ci potrebbe essere un "codice di odore" qui, ma non sono sicuro. Da un lato, questi metodi di produzione sono necessariamente descrittivi. D'altra parte, posso prevedere che questi nomi di metodo sfuggano al controllo. Ad esempio, come dovrei denominare un metodo di fabbrica Triangolo che crea un triangolo dato un punto, la lunghezza di un lato, un angolo e la lunghezza di un altro lato? Triangle.createWithPointSideAngleAndSide(x, y, side1, angle, side2)? È solo cattivo?

Se si dovesse utilizzare questa API, i nomi dei metodi come questo vanno bene per te? Hai dei consigli su come posso rendere più sani i nomi dei metodi?

+0

con cosa sei andato? – eglasius

+0

Sto cambiando i metodi per essere chiamato 'da', come nel post di Jason. Sto rimuovendo alcuni dei "non necessari" e, secondo il commento di Joe_M, al post di kevchadder. Ho considerato la tua idea fluida di interfaccia; Sto usando Java, quindi non ho parametri con nome. Mi piace l'idea di Slim, vedere se è fattibile. –

+0

E, ho intenzione di seguire quando ho finito una bozza della mia API, che dovrei essere presto. –

risposta

0

Sì, questa è più di una meta-risposta, ma ti suggerisco di dare un'occhiata a come viene effettuata la denominazione in Apple's Cocoa.

11

Va bene in qualsiasi lingua che non supporta i parametri denominati. Se la lingua supporta i parametri denominati, mi piace di più la creazione breve e solo i nomi dei parametri ovvi.

Per una lingua con parametri denominati, si farebbe:

Circle.Create(
    centerX = cx, 
    centerY = cy, 
    radius = r 
); 

Un'altra opzione più coinvolto, sarebbe un'interfaccia fluida simile (ma che probabilmente è troppo):

circleBuilder.Center(cx,cy).Radius(r) 
circleBuilder.Center(x,y).Width(w).Height(y) 
circleBuilder.BoundWith().Left(x1,y1).Right(x2,y2) 

rendimenti Centro un'istanza di una classe intermedia che consente solo Raggio o Larghezza. E BoundWith ne restituisce uno che consente solo Sinistra.

+0

Questo è un sacco di codice da creare. Penso che ti perderebbe molto tempo a creare quel codice e poi tentare di generarlo in modo che funzioni anche quando crei un rettangolo o un triangolo. – jmucchiello

+0

@Joe, l'ho aggiornato da "ma potrebbe essere troppo" a "ma probabilmente è troppo". – eglasius

14

Si potrebbe modificare i vostri metodi cerchio di

Circle.FromCenterAndRadius(...) 
Circle.FromBoundingBox(...) 
Circle.FromWidthAndHeight(...) 

Ciò implica che si sta creando cerchi da loro diverse rappresentazioni in una sorta di modo conciso ...

+0

+1 Mi piace il miglioramento :) – eglasius

1

Per le lingue che non supportano parametri nominati, sarebbe più pulito rendere il nome del metodo qualcosa di molto semplice come Circle.create e quindi aggiungere semplicemente una stringa di flag di input aggiuntiva (come "center" o "bounding") che indicava come i valori di input dovevano essere interpretati per casi che sono difficili da discriminare basandosi solo sull'input v numero e tipo di ariable? I svantaggi di ciò consistono nel fatto che richiede una logica extra all'interno del metodo per gestire diversi tipi di argomenti di input e richiede inoltre che l'utente ricordi le opzioni di flag.

1

Avrei i metodi CreateTriangle e il sovraccarico mostra le diverse informazioni richieste.

E.g.

Circle.CreateCircle(cx, cy, r) 
Circle.CreateCircle(point1, point2) 
Circle.CreateCircle(point, width, height) 
+0

+1: concordato. Così farò anche io ... Lascia che i parametri sovraccaricati parlino da soli. – Cerebrus

+0

er, qui ci sono due metodi con gli stessi parametri (supponendo che tutti i parametri siano di un tipo intero). – slim

+0

hai corretto, sarebbe meglio usare una classe Point più di due inte per differenziare – cjk

8

penso che ci sia niente di sbagliato con i vostri metodi descrittivi - sono la compatta e descrivere esattamente cosa sta succedendo. Gli utenti della biblioteca non avranno dubbi sulla funzione dei tuoi metodi, né sui programmatori di manutenzione.

Si potrebbe anche applicare qualche schema di progettazione qui se si è veramente preoccupati di esporre un gran numero di metodi di fabbrica, come avere metodi di fabbrica con classi di proprietà. Si potrebbe avere una classe CircleProperties con proprietà come CenterX, CenterY, Radius, (bool) UseCenterX, (bool) UseCenterY ecc e quindi si passa al metodo factory pubblico che determinerà quale metodo (privato) di fabbrica utilizzare.

Supponendo che C#:

var circleProperties = new CircleProperties() 
{ 
    CenterX = 10, 
    CenterY = -5, 
    Radius = 8, 
    UseCenterX = true, 
    UseCenterY = true, 
    UseCenterRadius = true 
}; 

var circle = Circle.Create(circleProperties); 
+0

Hai davvero bisogno delle proprietà "UseX"? Non potresti semplicemente controllare quali proprietà sono state impostate (non sono nulle)? Oppure impostali in setter per le altre proprietà (ad es. SetCenterX() imposta UseCenterX)? – TMN

+0

TMN: Puoi, ma poi devi davvero selezionare i tuoi numeri magici in modo corretto ... Ovviamente, 0.0 è una coordinata totalmente valida. Impostare questi booleani automaticamente nel setter appropriato è comunque una buona idea. –

6

Il mio primo istinto è quello di avere più tipi, che consentirebbe per il metodo più intuitivo sovraccarico.

// instead of Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.create(new Point(cx,xy), r); 

// instead of Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.create(new Point(x1,y1), new Point(x1,y1)); 
// or even... 
Circle.create(new Box(p1,p2)); 

// instead of Circle.createWithWidthAndHeight(x, y, w, h) 
Circle.create(new Point(x,y), w, h); 

Così come Point, è possibile definire Distanza (che consentirebbe di diverse unità)

Se questo stile vi si addice, prendere in considerazione perché avete bisogno di un metodo di fabbrica invece di un costruttore.

Circle c = new Circle(new Point(cx,xy), r); 
-1

Lo so, lo so. Questo suona completamente pazzo per te C/C++/Java, ma gli esempi forniti nella domanda e in tutte quelle risposte dimostrano chiaramente che una convenzione cattiva e cattiva CamelCaseNaming è davvero.

Diamo un altro sguardo l'esempio originale:

Circle.createWithCenterAndRadius(cx, cy, r) 
Circle.createWithBoundingBox(x1, y1, x2, y2) 
Circle.createWithWidthAndHeight(x, y, w, h) 

E ora cerchiamo di sbarazzarsi di quel caso cammello notazione

Circle.create_with_center_and_radius(cx, cy, r) 
Circle.create_with_bounding_box(x1, y1, x2, y2) 
Circle.create_with_width_and_height(x, y, w, h) 

Questo può sembrare terribilmente unfamilar, ma onesti: quale versione è più facile da leggere?

+0

Non è un cattivo esempio - in realtà è leggermente più facile da leggere - ma completamente irrilevante. Non è come se qualcuno dovesse cambiare o qualcosa (e MAN sarebbe cattivo se qualcuno lo facesse !!) Allora, cosa stai cercando di realizzare? –

+0

Nota: quando sono in Java, utilizzo la sintassi Java, quando sono in Ruby ho usato la sintassi Ruby. Non sentivo il bisogno di passare da un utente all'altro - entrambi sono abbastanza leggibili. ps. Sebbene il rubino sia un po 'più facile da leggere, il java è molto più facile da digitare. –

0

Il tuo istinto è corretto - l'intero schema di creazione delle cose in questo modo è - incerto.

A meno che non vengano utilizzati solo una o due volte, diventeranno piuttosto disordinati. Se stessimo creando una forma con 5 cerchi e 3 triangoli, sarebbe un disastro.

Tutto ciò che va al di là di un semplice esempio potrebbe essere fatto meglio con una sorta di implementazione basata sui dati.

Verso quelle estremità, avere una stringa, un hash o XML per definire le forme potrebbe essere estremamente utile.

Ma tutto dipende da come ci si aspetta che vengano utilizzati.

Ho lo stesso tipo di problemi con la creazione di controlli Swing in Java. Si finisce con una riga dopo l'altra di "new Button()" seguito da un gruppo di chiamate di proprietà .set nonché una riga di codice per copiare il valore in un oggetto (o aggiungere un listener) e una riga per reimpostare il valore..

Questo tipo di piastra non dovrebbe mai accadere nel codice, quindi di solito cerco di trovare un modo per guidarlo con i dati, legando i controlli agli oggetti dinamicamente - e verso tale fine, un linguaggio descrittivo basato su stringhe sarebbe molto utile.

+0

Il tuo suggerimento ha sicuramente valore. Potresti fornire un breve esempio di implementazione basata sui dati? Per "stringa", stai implicando qualcosa come un linguaggio specifico del dominio (DSL)? –