terça-feira, 11 de dezembro de 2018

Lembrando dos Natais Passados: Monark BMX

Bem... Eu nunca fui bom com "coisas com rodas", mas teve uma conversa com um pessoal sobre os tempos de criança e falou-se sobre uma tal de BMX Monark:


Me lembro de ter visto estas propagandas nas revistinhas da Turma da Mônica, quando ainda era publicada na Editora Abril...

Mas não me lembro desta bicicleta ter marcha, nem que dava para pular assim, quase no céu, sem se espatifar no asfalto (a bicicleta e quem estava nela...).

Quem diria que a gente era tão inocente de achar que essa era "a" bicicleta (tempo que a TV era o mais rápido meio de comunicação...).

Bons tempos! (eu acho... :P )

Até mais!

quinta-feira, 6 de dezembro de 2018

Tartarugas Ninjas na vida real

E se, as Tartarugas Ninjas fossem gente de verdade, como é que seria um treinamento entre eles? 

Hum... Sinceramente, acho que seria mais ou menos assim:


Aonde será que esta a April? :P

Até mais!

segunda-feira, 19 de novembro de 2018

Isso é MVP (Model-View-Presenter)? Reflexão e questões

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!

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();
              ...
       }
       ....
}

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();
              ...
       }
       ....
}

Acho que é isso... Se eu esquecer de alguma coisa, depois eu arrumo. (errar é humano, ainda mais depois dos 40... :P )

Até mais!

quarta-feira, 31 de outubro de 2018

Isso é MVP (Model-View-Presenter)? Segunda parte - View

Bem, tenho que corrigir uma coisa anteriormente: o método "login" esta síncrono, seria melhor se ele fosse assincrono, ou usando callbacks:

public function login(username: string, password: string, callback: function(user: User?, error: Error)) {
}

ou usando métodos de delegação de uma interface (que será implementada na classe de Presenter):

public interface ILoginModelDelegate {
      public function onLoginSuccess(user: User);
      public function onLoginError(error: Error);
}

Beleza, agora podemos continuar! (se eu não me lembrar de nada até lá...)

Se para Model, a gente fez uma interface para ela (para facilitar a mudança da origem de dados -- seja serviços REST, SOAP ou banco de dados), a gente faz a mesma coisa para a View.

Por que? -- você deve perguntar...

Pelo mesmo motivo: desacoplamento, ou seja, para que a nossa "tela" possa mudar de HTML para um serviço que retorna json ou para outro que retorna XML:

public interface ILoginView {
        public property (readonly) username: string;
        public property (readonly) password: string;
        public function onLogin(user: User);
        public function onLoginFail(error: Error);       
}

public class LoginPageView: Page, ILoginView {
        public property (readonly) username: string {
                 return txtUserName.text;
        }
        ...
}

public class LoginRestView: Rest, ILoginView {
        public property (readonly) username: string {
                 return request.getParameter("username");
        }
        ...
}

Legal, né?

Bem, acho que é isso... Na próxima fica faltando só a Presenter. :)

Até mais!

quarta-feira, 24 de outubro de 2018

Isso é MVP (Model-View-Presenter)? Primeira parte - Model

Sabe aquele tipo de cara que aprende somente na prática? Então, este sou eu (por isso, eu não tenho certeza se isso é MVP).

MVP é uma sigla para Model-View-Presenter (modelo, visão e apresentação), que é um tipo de modelo de arquitetura de software, como o MVC.

Como este, seguimos o padrão de separar o "negócio" (regras, cálculos, verificações, dados, etc.), o "M" da sigla, da tela (bem, tela é tela :P), o "V" da sigla.

Se separamos, existe alguém que junta, certo? Sim, e este "juntador" é representado pela letra "P" (o Presenter).

Bem, melhor que explicar, vamos a codificação (programador entende melhor "programando"). Primeiramente, vamos entender as classes de modelo:

public interface IUserModel {
        //Função que verifica se o usuário é válido.
        //@param username string que contém o nome do usuário (obrigatório) 
        //@param password string que contém a senha do usuário (obrigatório)
        //@return se os valores foram válidos, retorna um objeto da classe User, com as informações do usuário, caso o contrário, retorna null
        public function login(username: string, password: string): User?;
}

//Implementação da interface IUserModel que usa banco de dados
public class UserDatabaseModel: IUserModel {
        @implementation
        public function login(username: string, password: string): User? {
             ...
        }
}

Por que temos uma interface em modelo? Por causa da teoria de "baixo acoplamento", e por que podemos, em vez de usar uma classe que conecta em banco de dados, usar uma classe que conecta em serviços REST, por exemplo:

//Implementação da interface IUserModel que usa serviços REST
public class UserRESTServiceModel: IUserModel {
        @implementation
        public function login(username: string, password: string): User? {
             ...
        }
}

Na hora de usar essas, em vez de instanciar um objeto da própria classe:
public property model: UserRESTServiceModel = new UserRESTServiceModel();

Podemos instanciar um objeto da interface:
public property model: IUserModel = new UserRESTServiceModel();

E, assim, utilizar um serviço ou outro, só mudando a instância:
public property model: IUserModel = new UserDatabaseModel();

Acho que a primeira parte esta concluída, na próxima, veremos a "V" de view (não de vingança). :)

Até mais!

terça-feira, 23 de outubro de 2018

Gigante guerreiro Daileon!


Ontem, um colega meu falou sobre um provável "remake" do Jaspion...

Bem, pelo que ouvi de boatos, sei que a SATO Company tem os direitos da série e que a Toei Company autorizou que esta possa fazer um filme de sua personagem.

Mas são só especulações, nada muito confirmado ou feito...

Porém, parece que tem um pessoal que esta animado! Tipo seu Rafael Segnini, que fez a transformação do gigante guerreiro Daileon em 3D:


Ficou bem legal, não? :)

Até mais!