2012-02-17 12 views
8

Tipo di un titolo lungo, ma generalmente è la domanda.È una buona idea utilizzare gli aspetti come metodo per rimuovere i controlli difensivi dalla logica dell'applicazione?

voglio sapere se si pensa che la sua una buona idea per fare quanto segue.

Invece di:

public void buyItem(int itemId, int buyerId) { 
    if (itemId <= 0) { 

     throw new IlleglArgumentException("itemId must be positive"); 
    } 
    if (buyerId <= 0) { 

     throw new IlleglArgumentException("buyerId must be positive"); 
    } 
    // buy logic 
} 

voglio avere qualcosa di simile:

@Defensive("isPositive(#itemId, #buyerId)") 
public void buyItem(int itemId, int buyerId) { 
    // buy logic 
} 

Pensi che questo è un bene/terribile/troppo di fantasia/troppo lento? Se effettivamente pensa che la sua buona Stavo pensando di utilizzare SpEL per la sua attuazione, qualcuno ha qualcosa di meglio/più leggero/più veloce in mente?

Grazie,

risposta

3

non è necessariamente una cosa negativa però il vostro caso semplice può ben essere risolti con eccezione dichiarazioni (rather than assertions che inizialmente ho citato).

Sembra che stai introducendo il proprio insieme di annotazioni che altri sviluppatori nel progetto devono accettare e adattarsi. Tuttavia, una volta introdotte le annotazioni, sembra che un normale approccio Proxy sia un candidato migliore per risolvere il problema.

Per riassumere: il problema descritto può essere facilmente risolto utilizzando le alternative standard di Java, anche se in un caso più complesso potrebbe essere giustificato (ad esempio, @Secured in spring-security), soprattutto se si sta sviluppando il proprio quadro.

+0

e introduce un'altra lingua all'interno delle annotazioni . –

+0

In realtà questa domanda mi è venuta in mente esattamente come un effetto collaterale dell'uso di '@ Secured'. Ma dal momento che già usiamo '@ Secured' per la sicurezza a livello di metodo, sarebbe confuso usarlo per i controlli difensivi IMO, è per questo che sto chiedendo idee per farlo e poiché' @ Secured' e '@ PreAuthorize' usano SPEL I pensato che sia la scelta più ovvia. – Simeon

+0

Perché il downvote? – Simeon

2

ritengo sia

  • overengineering
  • rottura incapsulamento, basandosi su un aspetto esterno (che potrebbe o non potrebbe esserci) per mantenere invarianti dell'oggetto
  • confusione
  • non
  • efficiente
  • non aggiungendo alcun valore

Mi piace usare la classe Guava's Preconditions per questi controlli. Inoltre, tali controlli fanno parte della logica aziendale, IMHO.

+0

Sia che si tratti di business logic o no è soggettivo (probabilmente ... non sono sicuro che ci sia una definizione decisiva), ma è comunque all'interno del metodo :) e all'interno del metodo mi sento meglio (forse sono solo io) se Non leggo 10/20 righe di assegni, che è normale se stai cercando di essere sicuro al 100%. – Simeon

+1

Le precondizioni di Guava ridurranno il numero di linee, perché eviteranno i blocchi if. Se questi controlli sono così grandi da disturbarli, inseriscili in un metodo privato e chiama questo metodo privato. Ciò riduce i controlli a una sola riga. E se vuoi essere sicuro al 100%, allora non usare asserzioni (che possono essere disabilitate - e sono disabilitate per impostazione predefinita IIRC), e non usare un aspetto, che può essere disabilitato o installato in modo errato. –

+1

@downvoter: potresti non essere d'accordo con la mia risposta, ma ciò non lo rende inutile. Perché il downvote? –

0

preferisco l'approccio Java assertion.

  1. è un approccio standard, quindi tutti i (più?) Programmatori Java lo capiranno. Strumenti automatizzati ecc. Saranno in grado di analizzarli.
  2. non si ha nulla di sviluppare da soli. So che sembra banale, ma queste cose hanno l'abitudine di degenerare.

meno che non si può dimostrare che il vostro approccio è palesemente migliore o fare qualcosa di diverso, vorrei utilizzare gli utensili e le API Java che fornisce come standard.

+0

Questo è OK finché si è certi che sia [attivato] (http://docs.oracle.com/javase/1.4.2/docs/guide/lang/assert.html#enable-disable) quando è necessario deve essere. – McDowell

1

Sembra convalida.Cordiali saluti, esistono già diversi framework, controlla this question e OVal per esempio.

Non conosco le prestazioni, ma per me non è l'ingengeria: si mantiene solo il codice logico. Mi piace lavorare con quello.

2

Penso che intendessi annotazioni, non aspetti. Gli aspetti sono normalmente esterni al codice che consigliano. In ogni caso, puoi eseguire il tipo di convalida che hai evidenziato nel tuo post con JSR 303. Caso in questione:

public void buyItem(@Min(value = 1) int itemId, @Min(value = 1) int buyerId) { 
    // buy logic 
} 

ci sono due implementazioni ben noti di JSR 303:

+0

Voglio dire aspetti. Sono aperto a suggerimenti di approccio non di annotazione. – Simeon