2016-07-26 1 views
0

J'attendais 2.12 pour être en mesure d'utiliser le crochet onCreate, mais il semble qu'il a été poussé jusqu'à 2.13. Y a-t-il des suggestions pour un moyen de faire une alternative décente? Essentiellement, j'ai un trait et une classe abstraite comme suit:Scala OnCreate implémentation alternative

trait Issue { 
    def details: ... 
    def logic: ... 
    def toSimpleView: ... 
} 

abstract class AbstractIssue extends(source: IssueSource) extends Issue{ 
    val extraDetail: ... 
} 

Il existe plusieurs implémentations différentes de la AbstractIssue, et l'initialisation d'un problème que je veux la saisir et mettre une représentation simplifiée de celui-ci en une base de données, puis le renvoyer au code comme d'habitude. Le but est de ne le mettre dans la base de données qu'après avoir initialisé tous les champs de la classe enfant, et de n'avoir qu'à écrire ce code dans les champs AbstractIssue et Issue pour éviter de rechercher tous les enfants existants Issue.

Ma réaction instinctive à ce problème est d'ajouter ceci au constructeur abstrait:

abstract class AbstractIssue extends(source: IssueSource) extends Issue{ 
    val extraDetail: ... 
    Future { Thread.sleep(2000) }.foreach(_ => InsertIssue(this.toSimpleView)) } 
} 

Malheureusement, c'est une façon terrible de le faire, et je me bats pour trouver une solution propre. Quelqu'un a-t-il une idée?

+0

Peut-être DelayedInit, ce qui vous permet de faire ce que vous aimez avec initialiseur. Peut-être avez-vous besoin d'un truc pour savoir quand votre objet est suffisamment prêt. –

+0

Malheureusement DelayedInit est obsolète AFAIK. Mais oui, si je peux trouver un moyen de signaler quand tous les champs requis sont prêts je pourrais juste faire un futur qui attend jusque-là – Ophirr

+0

Vous pouvez faire 'toSimpleView' retourner un type' Future' comme 'def toSimpleView: Task [ ???] 'ou' def toSimpleView: Future [???] '. La méthode (ou quelque chose d'autre dans votre classe concrète) peut alors compléter la promesse lorsqu'elle a été complètement initialisée. Il semble que c'est un très mauvais design! Pensez à déplacer le côté 'InsertIssue' de' AbstractIssue' et laissez celui qui est responsable de la création des problèmes décider s'il veut les mettre dans la base de données. – valenterry

Répondre

0

Ce que je fini par faire comme un hack jusqu'à ce que onCreate sort:

def hackToHandleAfterInitialization(handler:IssueHandler):Future[Unit] = { 
import scala.concurrent.blocking 
Future { 
    var continue = true 
    while (continue) { 
    try { 
     blocking(synchronized(handler.handleProblem(this))) 
     continue = false 
    } catch { 
     case un:UninitializedFieldError => 
     Thread.sleep(5) 
     continue = true 
    } 
    } 
    Unit 
} 

Et puis dans la classe abstraite:

abstract class AbstractIssue extends(source: IssueSource) extends Issue{ 
    val extraDetail: ... 
    hackTohandleAfterInitialization(DefaultHandler()) 
}