2015-09-18 18 views
5

Sto cercando di scoprire se esiste un modo per interrompere funzioni/metodi dall'aggiunta (EDIT: da altri sviluppatori) a una classe per il caso in cui l'oggetto è un modello o DTO che non deve contenere metodi (per prevenire "l'abuso" dei Modelli/DTO da parte di altri, che potrebbero provare ad aggiungere metodi "helper", ecc.).Come posso impedire l'aggiunta di metodi a una classe?

Esiste un modo per raggiungere questo obiettivo?

+3

Semplicemente non farlo. –

+4

Scrive una regola CodeAnalysis (FxCop) o "Roslyn" personalizzata, aggiungila al processo di compilazione producendo un errore se violata. –

+0

@NickG la domanda è troppo ampia e un po 'confusa - cosa hanno a che fare le strutture con i metodi di prevenzione? Vuoi o non vuoi ereditare dalla classe? –

risposta

5

Utilizzare la riflessione e scrivere un test dell'unità che non riesce se una classe modello ha metodi.

Contrassegna tutte le classi del modello con un attributo personalizzato. Quindi esegui un test unitario che utilizza la reflection per caricare un determinato assembly, iterare tutte le classi di quell'assembly e verificare che le classi contrassegnate con l'attributo model non dispongano di metodi. Questo dovrebbe essere abbastanza semplice usando la riflessione.

+1

Non dimenticare di costruire un grafico di ereditarietà ed esaminare tutti i tipi derivati ​​per assicurarsi che non abbiano metodi. Se non ti puoi fidare di qualcuno di non aggiungere metodi, non puoi fidarti di loro per aggiungere il tuo attributo. –

+0

@Asad non preoccuparti - mi stavo chiedendo principalmente per curiosità piuttosto che per qualsiasi altra cosa :) Non abbiamo grossi problemi con questo e non posso nemmeno implementare le soluzioni proposte. Mi chiedevo solo se ci fosse una "soluzione rapida" – NickG

0

Non è necessario utilizzare una struttura per impedire aggiunte a una classe. È possibile utilizzare la parola chiave sealed

public sealed class MyDTOObject { ... } 

Ora, non si può inerente una classe e anche prevenire eredità (che è essenzialmente quello che stai chiedendo). Il fatto stesso di ereditare MyDTOObject sta creando una nuova classe che è basata su non uguale a, o limitata, o definita in alcun modo dall'implementazione di MyDTOObject.

È possibile utilizzare una classe abstract per forzare le classi derivate ad implementare determinati metodi, ma non viceversa.

Se si desidera impedire ad altri di derivare dalla classe e implementare metodi di supporto, è necessario utilizzare la parola chiave sealed o contrassegnare la classe interna.

+2

Penso che l'OP stesse chiedendo come impedire _any_ metodi, cioè anche in "MyDTOObject" stesso. –

+1

Penso che l'OP abbia il requisito di voler essere in grado di ereditare e aggiungere proprietà, solo non metodi. –

+1

@ Christian.K: e sto dicendo che è impossibile, oltre a rendere la classe sigillata per prevenire l'ereditarietà. (ha specificato aggiunte "da altri sviluppatori") – caesay

3

Credo che tu stia cercando di risolvere un problema procedurale con il codice in cui dovresti usare la comunicazione.

I tuoi colleghi (presumo) operano sui file di codice con i privilegi di "piena affidabilità". Se rompono questo privilegio, dovresti aprire un dialogo. Usa il cambiamento come un'opportunità per istruirli sul progetto previsto. Forse hanno ragione e sarai educato!

Suggerisco semplicemente di rendere evidente il design previsto nel nome della classe e con un commento che indica la natura desiderata. Forse citare i documenti di progettazione che hanno informato la classe.

2

Non è possibile hinder chiunque abbia accesso completo in scrittura al proprio code-base per farlo. Le uniche due cose che puoi fare a evitare sono creare qualche regola CodeAnalysis per FXCop come menzionato da Christian.K nei commenti o scrivendo la tua classe DTO in modo che sia indubbiamente un DTO che non dovrebbe avere alcun metodi usando un nome non ambizioso per la classe e se questo non è sufficiente fornisci alcuni commenti di codice che notificano al programmatore di non farlo.

Tuttavia, potrebbe essere necessario un qualche tipo di metodo se si utilizzano le raccolte ad es. dove avrai bisogno di una sorta di comparazione se due istanze del tuo DTO sono uguali, quindi devi fornire almeno un metodo Equals - e GetHashCode.

0

È possibile impedire che la classe venga estesa o ereditata contrassegnandola con finale in questo modo nessuno sarebbe in grado di estendere la classe e quindi non essere in grado di aggiungere alcun comportamento. Ma fermati e chiediti se vuoi farlo o no, perché poi firmi un contratto invisibile che tutto ciò che è richiesto dalla classe è scritto nella classe e questa classe non ha bisogno di ulteriori aggiunte.

Per essere chiari, stavo parlando in contesto Java.

Problemi correlati