2016-08-11 1 views
0

Bonjour, je suis novice dans l'utilisation de TornadoFX et je me demandais quelle serait la meilleure conception pour une structure MVP utilisant TornadoFX?TornadoFX - Création d'un design MVP

Dans MVP de la vue:

-> déléguerait tous les événements tels que cliquant sur le bouton à une fonction dans le présentateur

-> n'interagit pas avec le modèle

Voici quelques-unes des rugueux idées prototypes:

abstract class AbstractPresenter<View : tornadofx.View> : Controller() { 

var view: View by Delegates.notNull() 

fun attachView(view: View) { 
    this.view = view; 
} 
} 

Je crée un présentateur qui se fixe à un AbstractView:

abstract class AbstractView<out Presenter : AbstractPresenter<*>> : View() { 

abstract val presenter: Presenter 

} 

Maintenant, en utilisant dans un exemple:

class SampleTestView: AbstractView<SampleTestPresenter>() { 

override val presenter: SampleTestPresenter by inject() 
override val root: AnchorPane by fxml() 

val testButton: Button by fxid() 

init { 
    presenter.attachView(this) 
    testButton.setOnAction { presenter.doSomething() } 
    } 

} 

Le présentateur de l'échantillon:

class SampleTestPresenter: AbstractPresenter<SampleWindowView>() { 

fun doSomething() { 
    println("did it") 
} 

} 

Est-ce une mise en œuvre correcte du motif MVP en utilisant TornadoFX?

EDIT

a fait quelques changements:

class SampleWindowView : View() { 
override val root: AnchorPane by fxml() 
val presenter : SampleWindowViewPresenter by inject() 

val button:Button by fxid() 

init { 
    button.setOnAction { presenter.handleButtonClick() } 
    } 
} 


class SampleWindowViewPresenter : Controller() { 

val sampleView: SampleWindowView by inject() 

fun handleButtonClick() { 
    println("clicked") 
    } 
} 
+0

Pourquoi avez-vous besoin des classes abstraites? Les classes intégrées 'View' et' Controller' de TornadoFX fonctionnent très bien pour MVC, MVP, ou même MVVM (en dépit d'être nommé Controller). –

+0

De plus, 'View's sont aussi des singletons, donc vous pouvez juste mettre' val view: SimpleTestView par injection() 'dans votre présentateur. Je ne suis pas sûr de l'importance de la fonction onViewAttached. –

+0

@ RuckusT-Boom Oh, je vois que je ne savais pas que les vues sont des singletons. Les classes abstraites sont là pour imposer l'idée que pour chaque vue, il y a un présentateur attaché à celle-ci. J'ai apporté des modifications au message principal. N'hésitez pas à ajouter des suggestions – Zocp

Répondre

1

Pour résumer la discussion ci-dessus, vous pouvez simplement faire:

class SampleTestView : View() { 
    val presenter: SampleTestPresenter by inject() 

    override val root: AnchorPane by fxml() 
    val testButton: Button by fxid() 

    init { 
     testButton.setOnAction { presenter.doSomething() } 
    } 
} 

class SampleTestPresenter : Controller() { 
    val view: SampleTestView by inject() 

    fun doSomething() { 
     println("Did the thing") 
    } 
} 

Si vous voulez vous assurer que la vue a un présentateur, vous pouvez créer une vue abstraite et étendre toutes vos vues:

abstract class AbstractView<Presenter : Controller> : View() { 
    abstract val presenter: Presenter 
} 
+0

Merci de résumer la discussion. Je vais certainement utiliser les classes abstraites mais je ne suis toujours pas sûr de savoir comment les génériques pourraient être améliorés. Je voudrais utiliser Presenter: AbstractPresenter <*> ou utiliser Presenter: Controller être mieux? Aussi, si je voulais que le présentateur ait la vue, cela peut être fait de la même manière que dans le post original – Zocp

+0

Bien sûr, mais il me semble un peu bizarre de m'assurer que le présentateur ait une vue depuis que vous le pouvez. t utilisez des génériques pour forcer le présentateur et la vue à être jumelés. –

+0

Mais je ne connais pas votre cas d'utilisation, donc si cela fonctionne pour vous, allez-y. –