2012-07-12 15 views
8

Mi spiego ;-)scala inquinamento caso oggetto

entrambe le classi inferiori sono in pacchetto com.company.foo

RoleGroup.scala 
abstract class RoleGroup 
case object ADMIN extends RoleGroup 
case object MEMBER extends RoleGroup 

MailSender.scala 
abstract class MailSender 
case object ADMIN extends MailSender 
case object STAFF extends MailSender 
case object ACCOUNTANT extends MailSender 

Il problema qui è che ADMIN è ambiguo dal momento che non v'è separazione spazio dei nomi con caso degli oggetti. Sembra che ci possa essere solo un caso caso con nome univoco per pacchetto.

Suppongo di poter denominare gli oggetti case in base alla funzione a la mailADMIN, al ruoloADMIN e così via. O dovrei semplicemente creare Enum corretto e dimenticare gli oggetti del caso? O prendere qualche altro approccio?

+1

In questo caso sembra che utilizzare le enumerazioni sarebbe una buona idea dato che è possibile specificare 'RoleGroup.Admin' contro' MailSender.Admin' senza preoccuparsi dell'inquinamento dello spazio dei nomi. – adelbertc

+0

sì, quella sembra la strada da percorrere, solo cercando di vedere quali sono le opzioni. Forse gli oggetti case devono essere utilizzati solo nell'ambito locale o dove non ci sono possibilità di collisione di nomi. – virtualeyes

risposta

13

si potrebbe fare qualcosa di simile:

object RoleGroup { 
    sealed trait RoleGroup 
    case object ADMIN extends RoleGroup 
    case object MEMBER extends Rolegroup 
} 

e allo stesso modo per MailSender. Poi nelle situazioni in cui si sta utilizzando solo uno, si può fare import MailSender._ o viceversa, ma quando si utilizza entrambi si fa riferimento a loro come RoleGroup.ADMIN, ecc

Sia che tu voglia adottare questo approccio o utilizzare enumerazioni dipende in gran parte da come hai intenzione di usarli. In questo approccio, ogni "enum" è un tipo, mentre con Enum ogni enum è un valore. Il primo funziona meglio per la corrispondenza dei pattern, dal momento che il compilatore può verificare se le corrispondenze sono esaustive, la seconda è migliore (IMO) per lavorare con la serializzazione.

+0

+1 ammalato, bella soluzione, quello dovrebbe fare il trucco – virtualeyes

+0

fa davvero il trucco, inquinamento andato ;-) grazie! – virtualeyes

+0

sì bello, solo un commento è che spesso si desidera che il tratto sia definito allo stesso livello dell'oggetto in modo da definire una relazione di accompagnamento appropriata. In questo esempio non ha molta importanza, ma potrebbe essere utile se estendi la funzionalità dei tipi. –

8

Non hai bisogno di enumerazione qui, probabilmente come altrove. Tutto ciò di cui hai bisogno è il giusto namespacing. Trovo l'approccio compagna oggetto per essere il più benefitial:

sealed abstract class RoleGroup 
object RoleGroup { 
    case object Admin extends RoleGroup 
    case object Member extends RoleGroup 
    // also just in case 
    sealed case class SomeParameterizedGroup (
    param1: Any, 
    param2: Int 
) extends RoleGroup 
} 

Utilizzando in questo modo sarà molto vi ricorderà enumerazioni di Java, mentre anche fornendo con punti di forza di Scala:

def foo (roleGroup: RoleGroup) = 
    roleGroup match { 
    case RoleGroup.Admin => 
    case RoleGroup.SomeParameterizedGroup(param1, param2) => 
    } 

Si prega di notare che nella soluzione di Dan il tipo di roleGroup sarebbe RoleGroup.RoleGroup, il che sembra un po 'innaturale. Nota anche che i nomi in maiuscolo violano le convenzioni stilistiche di Scala e dagli esempi sopra puoi vedere perché.

+0

+1, vedo, quindi spostare il carattere all'esterno dell'oggetto associato, ha senso. – virtualeyes

+0

nell'oggetto soluzione di Dan non era un oggetto complementare, esso (oggetto) diventa compagno subito dopo il movimento tratto al di fuori di esso. – aeracode

Problemi correlati