2016-03-03 26 views
6

Ho una classe MyClass che ha un bug nell'implementazione. La classe fa parte di una libreria, quindi non posso modificare l'implementazione della classe perché cambierà silenziosamente il comportamento per i client esistenti (i client che in questo caso possono fare affidamento sull'errore: Vedi ad esempio (https://connect.microsoft.com/VisualStudio/feedback/details/790160/httpclient-throws-operationcanceledexception-insead-of-timeoutexception))Convenzione di denominazione: come denominare una versione diversa della stessa classe?

Ho bisogno di creare una seconda versione della stessa classe che include la correzione dei bug. Ho già visto situazioni come questa, ma il nome che ho visto era sempre incrementale, ad esempio MyClass2, MyClass3.

Questi casi sono probabilmente piuttosto rari, tuttavia mi chiedevo se esiste un modo migliore di nominare queste classi "con versione". Immagino una soluzione che cresca nel tempo e abbia più classi di questo tipo che possono diventare davvero davvero confuse soprattutto per una libreria. Immagino che a dover scegliere tra MyClass, MyClassV2, MyClassV3 ecc

+0

Non sono sicuro se esiste una convenzione di denominazione per questo, ma vorrei usare 'MyClassVX' e contrassegnare i precedenti obsoleti. – thijmen321

+0

Si potrebbe argomentare che questa domanda è principalmente basata sull'opinione, così come tutte le domande sulle convenzioni di denominazione. Forse la tua domanda potrebbe essere meglio accolta a [programmers.stackexchange.com] (http://programmers.stackexchange.com)? –

risposta

4

Mi chiedevo se c'è un modo migliore di nominare queste classi "con versione".

Non esiste una convenzione di denominazione .NET per "classi che risolvono bug in altre classi". Vorrei consigliare con altri sviluppatori sul posto di lavoro e vedere se hanno qualche convenzione aziendale per una cosa del genere. Penso che la coerenza sia più importante del nome attuale.

E su una nota a margine del problema, non creerei affatto una nuova classe. Contrassegnerei il metodo con DeprecatedAttribute e implementerei la logica all'interno della stessa classe, esponendo una nuova serie di metodi API che sono documentati correttamente per dichiarare che sono qui come una correzione. I client della tua libreria hanno probabilmente già familiarità con MyClass, e così facendo faciliterebbero l'uso per loro, interponendo loro la necessità di chiedersi ogni volta "quale versione di questo dovrei usare".

2

vorrei copiare tutti i comportamenti della classe esistente ad uno nuovo, rinominare quello originale per indicare che la classe è obsoleta, rinominare il nuovo ad il nome effettivo di prima e contrassegnare quello originale (con il nuovo nome ora) come [Obsolete] indicando che non dovrebbe essere più utilizzato. Quindi tutto il codice che consuma invoca automaticamente il nuovo comportamento. Quindi la tua nuova classe con il comportamento corretto ottiene il nome della classe originale, dove per esempio il buggy ottiene un numero di versione.

Per il codice legacy è possibile fare il contrario, creare una nuova classe con un nuovo nome e contrassegnare quella precedente come Obsolete. Conosco gli SDK con un numero di versione, in cui l'ultimo numero indica la versione più recente della classe e tutti gli altri hanno un attributo di questo tipo insieme a un avviso all'interno dei documenti che menziona il superamento della classe con una nuova versione.

0

Penso che il nome della classe di duplicazione possa confondere seriamente gli altri straordinari. Estrai il metodo con l'interfaccia C# e implementa diverse versioni.

7

In un mondo ideale, le nuove versioni introdurranno funzionalità aggiuntive pur restando al 100% retrocompatibili con le precedenti versioni dell'API. Sfortunatamente, il mondo ideale rimane sfuggente e non è sempre possibile mantenere la piena retrocompatibilità. Un suffisso con versione è lo schema appropriato in questo caso.

La convenzione di denominazione standard .NET è quello di utilizzare la numerazione incrementale, come Class, Class2, Class3, ecc .. Questo deriva dalla convenzione di denominazione per interfacce COM, progettate esattamente per il caso d'uso si sta descrivendo.Ad esempio, l'interfaccia IHTMLDocument ha attualmente 8 versioni, da IHTMLDocument fino a IHTMLDocument8.

Il Framework Design Guidelines libro originale, da Cwalina e Abrams, raccomandato esplicitamente questa pratica, con gli autori hanno a dire:

DO utilizzare un suffisso numerico per indicare una nuova versione API esistente, se il nome esistente dell'API è l'unico nome che ha senso (ovvero, è uno standard di settore) e l'aggiunta di qualsiasi suffisso significativo (o la modifica del nome) non è un'opzione appropriata.

// old API 
[Obsolete("This type is obsolete. Please use the new version of the same class, X509Certificate2."] 
public class X509Certificate { ... } 

// new API 
public class X509Certificate2 { ... } 

La vecchia convenzione, seguito dal team originale di Windows, è stato quello di aggiungere il suffisso Ex a nuovi e migliorato versioni di un'API, che deriva dalla parola "estendere". Questo non è in grado di scalare bene, tuttavia, portando a funzioni confuse con suffisso ExEx. Non penso ci fosse un ExExEx; tutti avevano paura di toccare quelle API. I Framework di progettazione Linee guida consiglia esplicitamente contro questa pratica, la gente che ha continuato a all'architetto .NET aver imparato la lezione:

NON usare il "Ex" (o simili) suffisso per un identificatore per distinguerlo da una versione precedente della stessa API.

[Obsolete("This type is obsolete. ..."] 
public class Car { ... } 

// new API 
public class CarEx  { ... }  // the wrong way 
public class CarNew  { ... }  // the wrong way 
public class Car2  { ... }  // the right way 
public class Automobile { ... }  // the right way 

Ovviamente, come loro ultimo codice sentori di esempio, se si sta aggiungendo il supporto per una specifica caratteristica nella nuova versione delle API, si sarebbe migliore fuori nominare la nuova classe/interfaccia con un riferimento a quella particolare caratteristica.

E sebbene quanto sopra si sia concentrato quasi esclusivamente su classi e interfacce, la stessa logica sarebbe valida per tutte le funzioni membro di quella classe che potrebbero essere aggiunte nelle revisioni successive. La funzione originale potrebbe mantenere il suo nome originale, con la funzione appena aggiunta con un nome diverso che riflette la sua iterazione o la sua funzionalità aggiunta.

+0

Votato per la pubblicazione su linee guida di progettazione e convenzioni di evidenziazione. Anche se i metodi deprecating sarebbero la mia soluzione preferita, questa soluzione particolare era necessaria in un caso limite che avevo. – David

0

Per chiarezza, se ciò accade, io uso ClassV2. Ciò indica che è un'altra versione della classe.