Hum... Fiquei pensando em algumas coisas após ter terminado o tutorial (se é que é um tutorial :P) ...
Uma das coisas é colocar o "assincronismo" na parte "Model" da coisa.
Pensando bem, se é a tela do Android (por exemplo) que trava por causa da resposta do serviço, por que diabos tenho que colocar o "assincronismo" no lado do serviço?
Eu poderia resolver com alguma coisa assim, no lado da View:
this.startLoading();
this.callAsync(presenter.callLogin, (returned: Object) throws Exception -> {
this.finishLoading();
if (object is User) {
...
} else if (object is Error) {
...
}
});
E colocar o Model e o Presenter síncronos.
E por que pensei nisso? Por causa que nem todas as aplicações pedem coisas assíncronas (por exemplo, um serviço de API que, na teoria, ao receber uma requisição, não seria necessário executar o serviço assíncrono).
Mas, se em todo o caso, os serviços (Models) são assíncronos (seja por que foi pensado assim, ou esteja utilizando uma biblioteca assíncrona) e você estiver precisando usar em alguma coisa síncrona, dependendo da linguagem, é possível fazer algo assim:
public function onRequest(request: Request, response: Response) {
...
presenter.callLogin();
this.wait();
if (this.user != null) {
...
} else if (this.error != null) {
...
}
...
}
public function onLogin(user: User) {
this.user = user;
this.notify();
...
}
public function onLoginFail(error: Error) {
this.error = error;
this.notify();
...
}
Tomara que, desta vez, eu tenha acertado! :P
Até mais!
segunda-feira, 19 de novembro de 2018
sexta-feira, 16 de novembro de 2018
Isso é MVP (Model-View-Presenter)? Terceira (e acho que última) parte - Presenter
Como muita gente viu, eu arrumei a parte dois (realmente, fazer as coisas com pressa dá nisso...).
Vamos a última parte (eu acho), a implementação da classe Presenter.
Esta classe tem como característica juntar a parte View (da segunda parte deste artigo) com a Model (da primeira parte deste mesmo).
Então temos:
//Classe de Presenter que implementa a delegação do Modelo (ILoginModelDelegate) e da View (ILoginViewDelegate)
public class LoginPresenter implements ILoginModelDelegate, ILoginViewDelegate {
//Propriedades privadas
private property model: ILoginModel;
private property view: ILoginView;
//Construtor da classe
public constructor(view: ILoginView) {
//Cria o model através de uma Fábrica (Factory)
model = Factory::instance.getModel(ILoginModel.class);
model.delegate = this;
view.delegate = this;
}
//Função de login
private function login() {
model.login(view.username, view.password);
}
@implementation
public function onLoginSuccess(user: User) {
view.onLogin(user);
}
@implementation
public function onLoginError(error: Error) {
view.onLoginFail(error);
}
@implementation
public function callLogin() {
login();
}
}
E, assim, temos a junção de tudo. Por exemplo, se fosse uma "página web":
public class LoginPageView: Page, ILoginView, OnClickListener {
private property presenter: LoginPresenter;
private property @UI okButton: UIButton;
...
public constructor() {
...
presenter = new LoginPresenter(this);
okButton.setOnClickListener(this);
...
}
...
@implementation
public function OnClick(sender: UIObject) {
presenter.callLogin();
}
....
}
Se fosse uma "Activity do Android":
public class LoginActivity: Activity, ILoginView, OnClickListener {
private property presenter: LoginPresenter;
private property okButton: Button;
...
@override
public function onCreate(savedInstanceState: Bundle) {
...
presenter = new LoginPresenter(this);
okButton.setOnClickListener(this);
...
}
...
@implementation
public function OnClick(sender: View) {
...
presenter.callLogin();
...
}
....
}
Vamos a última parte (eu acho), a implementação da classe Presenter.
Esta classe tem como característica juntar a parte View (da segunda parte deste artigo) com a Model (da primeira parte deste mesmo).
Então temos:
//Classe de Presenter que implementa a delegação do Modelo (ILoginModelDelegate) e da View (ILoginViewDelegate)
public class LoginPresenter implements ILoginModelDelegate, ILoginViewDelegate {
//Propriedades privadas
private property model: ILoginModel;
private property view: ILoginView;
//Construtor da classe
public constructor(view: ILoginView) {
//Cria o model através de uma Fábrica (Factory)
model = Factory::instance.getModel(ILoginModel.class);
model.delegate = this;
view.delegate = this;
}
//Função de login
private function login() {
model.login(view.username, view.password);
}
@implementation
public function onLoginSuccess(user: User) {
view.onLogin(user);
}
@implementation
public function onLoginError(error: Error) {
view.onLoginFail(error);
}
@implementation
public function callLogin() {
login();
}
}
E, assim, temos a junção de tudo. Por exemplo, se fosse uma "página web":
public class LoginPageView: Page, ILoginView, OnClickListener {
private property presenter: LoginPresenter;
private property @UI okButton: UIButton;
...
public constructor() {
...
presenter = new LoginPresenter(this);
okButton.setOnClickListener(this);
...
}
...
@implementation
public function OnClick(sender: UIObject) {
presenter.callLogin();
}
....
}
Se fosse uma "Activity do Android":
public class LoginActivity: Activity, ILoginView, OnClickListener {
private property presenter: LoginPresenter;
private property okButton: Button;
...
@override
public function onCreate(savedInstanceState: Bundle) {
...
presenter = new LoginPresenter(this);
okButton.setOnClickListener(this);
...
}
...
@implementation
public function OnClick(sender: View) {
...
presenter.callLogin();
...
}
....
}
Ou se fosse um "serviço JSON":
public class LoginJSONView: JSON, ILoginView {
private property presenter: LoginPresenter;
...
public constructor {
...
presenter = new LoginPresenter(this);
...
}
...
@override
public onPost(request: Request, response: Response) {
...
presenter.callLogin();
...
}
....
}
public class LoginJSONView: JSON, ILoginView {
private property presenter: LoginPresenter;
...
public constructor {
...
presenter = new LoginPresenter(this);
...
}
...
@override
public onPost(request: Request, response: Response) {
...
presenter.callLogin();
...
}
....
}
Acho que é isso... Se eu esquecer de alguma coisa, depois eu arrumo. (errar é humano, ainda mais depois dos 40... :P )
Até mais!
Assinar:
Postagens (Atom)