David Anderson Lino (Developer's Blog)

19Set/111

Implementando MVVM em WPF

Comecei a trabalhar com WPF, e procurei alguma forma para conseguir uma melhor Separation of Concerns(SoC).

Um dos padrões que possibilitam isto é o MVVM. O Elemar escreveu um ótimo post sobre a parte teórica do padrão, então decidi utilizar este padrão e esta é a forma que o implementei.

Eu tenho uma classe Pessoa com o atributo "Nome" e uma tela onde desejo alterar o Nome, e salvar esta pessoa em algum lugar.

Minha classe pessoa é a seguinte:

public class Person {
   public string Name {get;set;}
   public int Age {get; set;}
}

Porém nesta minha tela só preciso utilizar o atributo pessoa, crio então um ViewModel que vai ser uma representação dessa classe do meu modelo, para esta view específica, o ViewModel fica assim:

public class PersonVM: INotifyPropertyChanged
{
    private string nameValue;
 
    public string Name
    {
        get{
            return nameValue;
        }
        set
        {
            if (value != this.nameValue)
            {
                this.nameValue= value;
                NotifyPropertyChanged("Name");
            }
        }
    }
 
	//You probably would cache this command, remeber this is just an example...
    public ICommand ChangeName{ get { return new ChangeNameCommand(); } }
 
    #region INotifyPropertyChanged Members
 
    public event PropertyChangedEventHandler PropertyChanged;
 
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
 
    #endregion
}

 

Percebam que minha classe implementa a interface INotifyPropertyChanged . Esta interface é usada para notificar clientes que uma certa propriedade teve seu valor alterado. Neste caso, o cliente vai ser a tela propriamente dita.

A ViewModel também encapsula o comportamento necessário para executar a lógica, este comportamento é exposto através de Comandos. Comandos são classes que implementam a interface ICommand. Este comando será ligado à view através de Bindings, e a classe ChangeNameCommand é:

public class ChangeNameCommand: ICommand
{
    #region ICommand Members
 
    public bool CanExecute(object parameter)
    {
        return (parameter as PersonVM) != null;
    }
 
    public event EventHandler CanExecuteChanged;
 
    public void Execute(object parameter)
    {
            PersonVM person = parameter as PersonVM;
            if(person != null)
                //Actually Save the person...
    }   
 
    #endregion
}

 

Ok, como vou usar isto? Aqui está a minha tela:

    <button name="Salvar">Save</button>

 

No meu TextBox eu digo que ele estará ligado (Binding) à propriedade Name. Han? Propriedade Name? Sim! Em WPF,  a propriedade informada no atributo Binding é procurada no objeto que está no DataContext desta classe. Ou seja, se meu DataContext possuir uma propriedade 'Name' ela estará ligada à este controle.

Isto quer dizer que, qualquer alteração no conteúdo do controle (neste caso, digitar algo), será refletida no objeto armazenado no DataContext. Se o DataContext implementa INotifyPropertyChanged então qualquer mudança no objeto será refletida no controle (O valor da propriedade aparece como texto).

Ok?

Outro Binding realizado é o Binding com o comando ChangeNameCommand. O controle, quando acionado, irá executar o comando passado presente no Binding, como o controle é um botão, o comando será invocado ao clicar no mesmo. Vale ressaltar que também é passado um parâmetro para o comando, neste caso o parâmetro é o próprio objeto no DataContext.

Como instanciar esta tela? Antes de a exibirmos, setamos o DataContext para o objeto adequado da seguinte forma:

PersonVM viewModel = //get View Model from Model
ChangeNameScreen screen = new ChangeNameScreen();
screen.DataContext = viewModel;
screen.Show();

 

E como isso tudo funciona no fim das contas?

  1. Instancia-se / carrega um objeto do tipo Pessoa de algum lugar (banco/memória)
  2. A tela ChangeName é criada;
  3. A pessoa obtida anteriormente é atribuída à propriedade DataContext da tela;
  4. A tela é exibida;
  5. Ao digitarmos qualquer coisa no TextBox, este valor é setado na nossa pessoa;
  6. Ao clicarmos no botão, a tela verifica se é possível verificar o comando, para aquele parâmetro;
  7. O comando verifica se o parâmetro é realmente do tipo do nosso ViewModel e retorna;
  8. Com a confirmação, a view executa o comando passando o DataContext como parâmetro;
  9. A alteração é tratada pelo nosso modelo;
  10. A tela retoma o controle da execução.

Simples não? Desta forma temos a nossa lógica de interface apenas no code-behind da view, completamente isolada da lógica de negócio, que está no nosso modelo, e é acessado através dos comandos.

Surgiram alguns padrões para facilitar a aplicação deste padrão como o RelayCommand e o DelegateCommand. Bem como alguns frameworks, como o Caliburn, Cinch e Prism. Ainda não tive a necessidade de usar nenhum deles, alguém aí tem algo a comentar?

 

1Set/1158

Não faltam profissionais qualificados em TI, mas empresas qualificadas!

Esta semana no Twitter, me inspirei para fazer meu primeiro post não técnico do blog.
A motivação veio deste twit: "Cadê a reportagem no Fantástico sobre profissionais que tem dificuldade de encontrar empresas qualificadas?".

Nos últimos meses, regularmente vejo reportagens com título similar a: "Faltam pessoas qualificadas no mercado de TI". Se você procurar por esta frase numa engine de busca qualquer, com certeza irá encontrar várias reportagens. Tem reportagem da Veja, da Info, da Exame. Enfim, inúmeras reportagens tratando do assunto, mas aí pergunto:

Realmente falta qualificação nos profissionais? Depende do ponto de vista... As empresas de TI estão hoje pedindo cada vez mais, e oferecendo cada vez menos, como este caso aqui. Não é difícil encontrar ofertas como essa (na verdade a maioria das ofertas se assemelha a esta), onde exigem muito conhecimento e experiência, e oferecem muito pouco.

Além do que, várias dessas 'exigências' são inviáveis. Tem como o cara ser especialista em Web, Mobile e Desktop ao mesmo tempo? Eu duvido muito. Saber os princípios, OK. Mas daí a ser experiente são mais quinhentos. Sendo assim, não existe realmente profissional "qualificado".

A questão é, muitas empresas sequer sabem o que querem, então tentam encontrar um super-herói que vá atender todas as necessidades deles, já recusei propostas assim. Ainda mais, muitos consideram que desenvolver um sistema é um trabalho fácil e simples, e dá para se fazer em pouquíssimo tempo, e assim subestimam seus próprios projetos e contratam menor quantidade de pessoas, e muitas vezes de qualidade contestável, dado o que andam ofertando.

Resultado? Projetos atrasados, inacabados e cancelados. O Standish Group está aí para provar isto.  Rola por aí uma comparação de "E se contratássem motoristas como se contratam programadores?". Infelizmente esta é a realidade hoje.

Para piorar a situação, muitos destes veículos de comunicação mentem com relação a expectativa salarial, completamente distante da realidade. Eu adoraria saber quais foram as fontes para reportagens como esta, que dizem que o salário médio de alguém que trabalha com suporte técnico varia de 1300 a  17 mil!!! Se alguém conhecer alguém de suporte ganhando mais de 5 mil me avisem que quero conversar com ele...

Além de outras reportagens com dados obtidos de forma errônea, como a reportagem no Olhar digital, onde falam que pagam, para desenvolvedores mobile, de 180 a 220 reais POR HORA! Fazendo as contas, o salário de um desenvolvedor desses seria de R$28.800 a R$ 35.200, No mesmo parágrafo dizem que os projetos variam de 20 a 30 mil. Ou isso tá muito errado, ou não sei mais matemática...

Pesquisando em sites como a CathoEmpregaTI, e nos perfis do twitter destinados a vagas de TI, a média salarial está bem abaixo dos 3 mil reais, e muitos exigem fluência em outro idioma, graduação e 2 anos+ de experiência...

Mas vamos supor que, por sorte, você consiga encontrar uma empresa que lhe oferece um salário de acordo com suas expectativas, bem acima da média do mercado. Ela é interessante?

Muitas das empresas que vejo atrás de profissionais, não deixa claro ao mundo externo como é sua cultura, ou pior, "criam" uma boa imagem externa, mas quando você entra, a coisa é outra.

Percebo que falta muito cuidado com a qualidade nas empresas(e também em muitos desenvolvedores) hoje... Ouço falar de pouquíssimas empresas que têm algum cuidado com isto.

Boas práticas? Muitas empresas sequer sabem o que é TDD, estímulo a se preocupar com isso então? Nem pensar. mas como alguém disse (Se alguém souber o autor me avise): "Se você não consegue testar seu próprio código, não deveria se chamar desenvolvedor profissional"

Processo de desenvolvimento? Não existe algum, as vezes existem apenas no papel, na prática é o XGH "by the book".

Agile? Nem pensar. Pior! Muitas ainda vendem a imagem de que "usam" o Scrum, ou tem processos "baseados" no mesmo, mas apenas para aproveitar a onda e ganhar um pouco de destaque, mas quando vai ver, o scrum passou longe e deixou apenas um quadro de ToDo/Doing/Done, e acreditam estar usando Scrum...(Isso rende assunto pra outros posts...).

Integração contínua? Eu, não consigo contar 10 pessoas que conheço no Brasil onde sua empresa *realmente* utiliza integração contínua.

Fora isso, existe o grande problema cultural na empresa, muitas vezes avessa as mudanças, preferindo continuar seguindo seu processo (ou, quase sempre, ausência do mesmo  / XGH) à investir em idéias novas (Se bem que processos como o XP já tem quase 15 anos de estrada) . Não estou defendendo que agilidade e as práticas citadas vão resolver todos os problemas, mas, no meu ponto de vista, seus princípios são os mais promissores atualmente.

E a qualidade de vida? Não é difícil encontrar anúncios onde um dos requisitos seja "Gostar de trabalhar sob pressão". Quem gosta disso? Nunca conheci...

Mas de onde vem essa pressão? De acordo com o que vejo, recentemente iniciou-se esta demanda imensa por profissionais, e nessa época também iniciou-se a 'prostituição' da área, como é costume chamar. O que aconteceu? As empresas começaram a iniciar vários projetos novos, começaram a contratar gente ruim pagando pouco e iniciaram seus projetos. Estes projetos estão começando a encostar na data final e não vai ser entregue, por motivos óbvios. Mais cedo ou mais tarde vão contratar pessoas realmente 'profissionais' para resolver os problemas que fizeram nos sistemas, e estes não vao cobrar barato. É a velha história do barato que sai caro.

Então as empresas terão 2 opções:

  1. Não conseguir contratar pessoas boas e/ou arcar com o prejuízo dos projetos e possivelmente falir (já presenciei situações como esta)
  2. Gastar muito dinheiro para remendar os erros gerados. E daí tem-se mais dois caminhos:
  • Investir em melhoria interna para conseguir atrair bons profissionais, e oferecer um salário justo.
  • Continuar errando e voltar para o ponto 1 até quebrar.
Ou seja, a culpa em grande parte, são das próprias empresas, que não se melhoram, e , como disse Einstein "A definição de Insanidade é fazer sempre a mesma coisa e esperar um resultado diferente.". Muitas também não oferecem condições justas de trabalho, e pior: Obrigam as pessoas a fazerem um trabalho lixo, por consequência dos deslizes dela no passado.Quem aqui gosta de fazer um trabalho ruim? Quem gosta de produzir algo do qual você não se orgulha? Eu definitivamente não.
Entrar em empresas para "apagar incêndios", ou participar de "forças-tarefa" não é para qualquer um, e não é nem um pouco fácil. Quero ver quem é o cara que consegue ser feliz trabalhando para otimizar um sistema, onde existem (várias) classes com 50+ campos, 70+ métodos, e 6k+ linhas! Eu já passei por isso, e não foi uma vez. True story!

Enfim, após este desabafo, não se pode mostrar apenas os problemas e não sugerir nada certo?
Aí fica a pergunta: O que podemos fazer?

  1. Trabalhar como freelancer, aproveitando o que você tem de melhor, por tempo indeterminado, ou até encontrar uma empresa interessante.
  2. Iniciar o processo de mudança onde trabalhamos.

Eu prefiro a opção 2, e venho fazendo isto por onde passo. Se você quer ser um bom profissional, aja com tal, e sirva de exemplo para seus colegas. Quando verem que o que você está fazendo dá certo, irão fazer também.

Ensine aos outros o caminho, acho difícil que as empresas lhe impeçam de fazer coisas como ministrar palestras, ou até mesmo lightning talks. Outra forma interessante de disseminar esta cultura é através de eventos como os Coding Dojos.

Não vou dizer que é fácil, pois não é. Mudanças bottom-up são bem complicadas, difíceis e lentas, mas é possível. Se não for, ou não ver resultados, não perca seu tempo e vá para outro lugar!

O que não acho justo fazer é sair sem sequer tentar. A idéia é ser como o beija-flor tentando apagar o incêndio.

 

Faça sua parte