domingo, 6 de dezembro de 2009

Metamorfose Ágil

Oi,

Venho passando por uma metamorfose nos últimos meses.

Uma metamorfose que está mudando definitivamente a minha maneira de pensar, trabalhar, falar e agir.
Uma metamorfose que iniciou após anos de confinamento e servidão a práticas que me cegavam a cada novo projeto de software.
Cronograma, Fase de levantamento, fase de especificação, fase de documentação, diagramas múltiplos, casos de uso extensos e detalhados, fase de testes, fase de homologação, distancia dos usuários, todos estes termos eram correntes pesadas que me prendiam ao mundo waterfall.

No entanto após conhecer o manifesto ágil, comecei a repensar os conceitos citados anteriormente, e comecei a buscar alternativas para a condução e desenvolvimento dos projetos de software.
Atualmente eu troquei as práticas citadas acima por, planejamento de entrega realista, TDD, integração contínua, participação ativa dos usuários, documentar o que precisa ser documentado, lições aprendidas a cada duas semanas, foco no ROI, auto gestão, programação em pares, dentre outras.
Acredito que após ter sofrido esta metamorfose terei muito mais responsabilidade com meus atos e ações nos projetos. Isto porque sempre defendi aquilo que acredito e não será diferente com o manifesto ágil, por isto terei que me preparar muito bem para não me contradizer quando precisar defender ou sugerir meu novo ponto de vista.

Espero ter sucesso nesta nova empreitada.

[]'s

Ricardo Simões

Quebrando o paradigma OEF

Oi,

Participando de uma reunião aonde precisava apresentar conceitos técnicos sobre o Dynamics CRM fui questionado a cerca do seguinte tema:

"Como posso ter certeza de que o código que o progamador está produzindo não está amarrado a uma versão específica do produto? Como vou conseguir me beneficiar de todas as novas features da nova plataforma do Dynamics CRM 5.0 e todas as outras que vierem pela frente?"

A pergunta acima teve um tom muito mais preocupante do que o que você utilizou para ler a frase acima, pode acreditar. Isto porque o cliente está decido a trocar uma ferramenta que já está em produção por mais de 10 anos em sua operação de call center.

Esta decisão foi tomada, pois na nova versão do produto ele terá que praticamente reescrever toda suas regras de negócios, já que toda a customização está literalmente engessada na versão atual do produto.

Minha resposta foi bem simples e objetiva:

"Só precisamos evitar o conceito OEF (Orientação a Entidade e Formulário)". Explico:

Tenho percebido ao longo do tempo que o Modelo Anêmico gerado pelo Dynamics CRM conduz os desenvolvedores por um caminho que muitas vezes pode ir de encontro ao problema que levou o cliente a decidir trocar sua solução de Call Center.

"Uma aplicação totalmente engessada a versão corrente."

Abaixo um exemplo de código OEF: (Algumas instruções foram ocultadas para um melhor entendimento).

public Guid Salvar(account cliente) {

var servico = new CrmService();
return servico.Create(cliente);
}

Se avaliarmos o exemplo acima e o modelo gerado pelo CrmService vamos perceber que as classes/entidades não possuem comportamento, caracterizando-se assim como classes anemicas. Isto é até compreensível, pois o MS CRM é um produto que pode atender a diversos segmentos e ter que respeitar regras dos mais diferentes tipos, como instituições financeiras, construtoras e empresas de cosméticos.

Contudo construir um código anêmico pode e deve ser evitado.

Uma maneira é utilizando conceitos como desacoplamento, abstração e, lembrar um pouco de como era trabalhar com o ADO.Net.

Neste momento você pode estar se perguntando: O que as classes geradas pelo CrmService tem em comum com as classes do ADO.Net?

Resposta muito simples: T.U.D.O!!!

Antes de você programar com o Sdk do Dynamics CRM sua biblioteca de acesso a dados estava basicamente baseada no ADO.Net. Agora esta mesma biblioteca está baseada em entidades geradas pelo CrmService.

Vejamos um exemplo prático: (Algumas instruções foram acultadas para um melhor entendimento)

public int Salvar(Cliente cliente) {

var parametro = new SqlParameter("@nome", cliente.Nome);
var comando = new SqlCommand("Insert Into Cliente(nome) Values(@nome)", "SqlConnection");
comando.Parameters.Add(parametro);
return comando.ExecuteNonQuery();
}

O Código acima é muito familiar, estou certo?

Agora vejamos o código abaixo, utilizando o Sdk do Dynamics CRM: (Algumas instruções foram ocultadas para um melhor entendimento)

public Guid Salvar(Cliente cliente) {

var parametro = new account();
parametro.name = cliente.Nome;
var servico = new CrmService();

return servico.Create(account)

}

Se analizarmos bem friamente os dois exemplos acima veremos que são muito parecidos no conceito, pois ambos encapusulam dos consumidores os objetos utilizados para manipular dados em alguma fonte de dados, seja ela um banco de dados ou um web service.

Ainda nos exemplos acima podemos notar que a assinatura dos métodos caracteriza-se por um objeto de domínio, utilizando inclusive o Ubiquitous Language no nossos código fonte, através do termo Cliente ao invés de account, como sugerido pelo Dynamics CRM.

A utilização de um modelo Orientado a Objetos é complexa e por isto é necessário ter cuidado quando se deseja adotar tal técnica. No entanto está mais do que comprovado de que é uma técnica que, quando bem aplicada, traz resultados significativos em termos de manutentabilidade e evolução do aplicativo. Sendo assim vale a pena um estudo de caso.

Para concluir gostaria de enfatizar que a utilização dos conceitos OEF não é uma evolução em sua carreira, ao contrário, vejo isto como algo que pode levá-lo ao comodismo e a prática de uma programação monopolista, engessada e amadora. Por isto reveja seus conceitos, entenda os principios da Orientação a Objetos e como aplicá-la ao mundo Dynamics, pois ao contrário do que pode parecer é uma prática totalmente viável, elegante e produtiva.


[]'s

Ricardo Simões

terça-feira, 11 de agosto de 2009

Simões X Cunha

Oi,
Desde que iniciei minhas atividades na Tridea tenho sido chamado de Ricardo Simões, contudo Simões não é meu último nome, e eu sempre preferi ser chamado de Ricardo Cunha. Até iniciei um movimento para derrubar o Simões.
No entando além de mais sonoro a maioria dos colegas de trabalho e clientes já se acostumaram a este nome e apesar dos meus esforços para mudar isto acabei chegando a conclusão de que realmente não haveria problema nenhum em manter este "Nome de Guerra".
Com isto a partir deste post, agora oficialmente, todos podem me chamar de Ricardo Simões que atenderei sem maiores problemas. :)

[]'s
Ricardo Simões

domingo, 5 de abril de 2009

Microsoft Dynamics CRM Developer Center

Olá Pessoas,

É impressionante como a cada dia a plataforma Dynamics CRM ganha mais força entre a comunidade de desenvolvedores. Abaixo duas novas fontes de pesquisas:

Microsoft Dynamics CRM Developer Center on MSDN
Microsoft Dynamics CRM code samples on MSDN

Boa diversão!

[]'s

Ricardo Cunha

Blog do Hamilton

Olá Pessoas,

Semana passada tive a oportunidade de conhecer uma personalidade da comunidade brasileira de Dynamics CRM, trata-se de Hamilton Oliveira.

O Hamilton é Microsoft Developer Evangelist focado em Dynamics CRM e recentemente inaugurou seu blog para contribuir ainda mais com a comunidade aqui no Brasil.

É a comunidade dinâmica ganhando cada vez mais força na terra do samba.

Boa sorte Hamilton!

[]'s

Ricardo Cunha

Microsoft Certified Business Management Solutions Professional Developer for Microsoft Dynamics CRM 4.0

Olá Comunidade,

Como sabemos a Microsoft possui uma série de certificações para reconhecer os profissionais que se especializam em uma determinada tecnologia, e com o Dynamics CRM não seria diferente.

Aqui segue um link sobre como tornar-se um Microsoft Certified Business Management Solutions Professional Developer for Microsoft Dynamics CRM 4.0. Inclusive pretendo me tornar um daqui há alguns meses. :)
Acho que o único inconveniente vai ser lembrar da sigla da certificação o tempo todo, afinal de contas MCBMSPD não é algo que se vê todo dia.
[]'s

Ricardo Cunha

segunda-feira, 16 de fevereiro de 2009

Qualidade Interna não é negociável!!!

Olá Pessoas!

Atualmente estou a estudar o
SCRUM. Nestes estudos encontrei o livro "Scrum e XP direto das trincheiras", é um livro extremamente prático e didático, ótimo para quem está começando, como eu.

Em uma das minha leituras encontrei a declaração abaixo:

"Generally speaking, a system with high internal quality can still have a
low external quality. But a system with low internal quality will rarely
have a high external quality. It is hard to build something nice on top of a
rotten fundament."


Logo após o autor explica:

External quality is what is perceived by the users of the system. A
slow and non-intuitive user interface is an example of poor
external quality.

Internal quality refers to issues that usually aren’t visible to the
user, but which have a profound effect on the maintainability of
the system. Things like system design consistency, test coverage,
code readability, refactoring, etc.

Após esta declaração o autor comenta que a "Qualidade Interna" não é tema de discussão sobre o escopo de um projeto ou requisito, pois é responsabilidade da equipe manter a qualidade do sistema sob todas as circunstâncias e isso simplesmente é inegociável.

Resumindo, PARE de achar que tudo que você desenvolve resume-se a um único método ou uma única classe, ou ainda pior, a um monte de classes que só espalham código sem o mínimo de coesão, rastreabilidade e possibilidade de escalabilidade.

Ao invés disto, pesquise, leia, discuta, teste, ouça. Existem muitos recursos em livros, sites, artigos, blogs que vão ajudá-lo a encontrar argumentos suficientes para fazer da "Qualidade Interna" um tema inegociável em seus projetos.

Pense nisso!

[]'s

Ricardo Cunha

terça-feira, 10 de fevereiro de 2009

WCF, JSON, Dynamics CRM - Uma mistura interessante.

Olá Pessoas,

Atualmente quando analiso desenvolvimentos para o MS CRM vejo uma tendência muito grande dos desenvolvedores acreditarem que XML e ASP.NET Web Services são os únicos recursos para um acesso remoto aos Serviços do CRM, quando estamos customizando um Formulário ou um botão ISV via Java Script.

Contudo se analisarmos o cenário mais friamente chegaremos a conclusão de que nem XML, muito menos Web Services serão a melhor solução quando estamos pensando em ganhos de desempenho (por conta do empacotamento e envio destes formatos que causam um overhead considerável no tráfego da rede), muito menos simplicidade na arquitetura, porque certamente você precisará pensar uma camada só para tratar o retorno de chamadas que são realizadas através de Java Script, a fim de manipular os dados no formato XML, que convenhamos, dá uma baita dor de cabeça quando temos cenários mais complexos de envio e recebimento de informações.

Algumas das alternativas para sanar problemas como os citados acima são o WCF e o formato JSON que, juntos, aliam ganho de performance e maior simplicidade no design na aplicação.

Abaixo segue um exemplo da utilização destes dois recursos:

Importante: Estou considerando neste exemplo que você já possui os conhecimentos de como criar um projeto WCF, publicá-lo para acesso através de HTTP e referenciar o SDK do Microsoft Dynamics CRM ao seu projeto.


1. Definição do contrato do Serviço

[ServiceContract]
public interface IClienteService {

[OperationContract]
account Obter(Guid accountId);

}

2. Implementação do contrato

public class ClienteService : IClienteService {

public account Obter(Guid accountId) {

// return CrmService.Retrieve("account", accountId, new AllColumns());

}

}

3. Arquivo de configuração do Serviço



[WebConfig.jpg]



4. Configuração da chamada Java Script

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");

// Informando o caminho do serviço e o métod que será executado

var url = http://localhost:1700/ClienteService.svc/Obter;

// Configuração no formato JSON
var accountId = '{"accountId":"' + '{6f5cfcf2-ba2d-481c-bd85-5c03ba8a652d}' + '"}';

xmlHttp.open("POST", url, false);
xmlHttp.setRequestHeader("Content-type", "application/json; charset=utf-8");
xmlHttp.setRequestHeader("Content-Length", data.length);
xmlHttp.send(accountId);

// Método que disparado após a execução da pesquisa
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4) {

var account = eval('(' + xmlHttp.responseText + ')').d;

alert(account.accountid.Value);
alert(account.name);

}
}

No exemplo acima estamos fazendo uma consulta a base do MS CRM utilizando como "Proxy" um serviço WCF que expõe um tipo complexo do MS CRM, sem a necessidade de se criar uma camada adicional para tratar o retorno do MS CRM para um tipo qualquer, como XML, por exemplo.

Já no lado Client, fica claro que a configuração da pesquisa ficou muito mais simplificada. Além disto, devido a utilização do formato JSON podemos trabalhar com o objeto "account" da mesma forma se estivessemos manipulando este objeto no C#.

Um outro aspecto importante é quanto ao desempenho desta chamada, pois não se fez necessário o empacotamento no protocolo SOAP, livrando-nos assim de uma quantidade excessiva de tags XML. Neste caso as únicas informações submetidas são o valor -- {"accountId":"{6f5cfcf2-ba2d-481c-bd85-5c03ba8a652d}"}--, que está no formato requirido pelo padrão JSON, e os valores de Content-Type e Content-Length adicionados ao Header da requisição.

Como vimos com WCF e JSON podemos criar uma mistura no mínimo interessante como alternativa aos famigerados Web Services e XML no acesso as informações, via JavaScript, dentro da plataforma Dynamics CRM.

[]'s


Ricardo Cunha



segunda-feira, 2 de fevereiro de 2009

Dependecy Injection no MS CRM

Olá Pessoas,

Desde muito tempo sou amante dos Design Patterns e, por conta disto, sempre que tenho contato com uma aplicação de software tento de alguma maneira identificá-los para aperfeiçoar cada vez mais meus conhecimentos quanto a suas aplicações.


Quando desenvolvemos para o Microsoft Dynamics CRM temos acesso há um Pattern chamado Dependecy Injection que é extremamente útil e complexo, mas que, na maioria dos casos, os desenvolvedores nem sabem que estão utilizando tal conceito. Claro que na prática isto não importa muito, mas para nosso crescimento e aperfeiçoamento como desenvolvedores ter o conhecimento de tal mecanismo, ao menos na minha ótica, pode ser fundamental.

O Pattern Dependecy Injection, como o próprio nome sugere, permite que você injete uma dependência dinâmica a sua aplicação, a fim de prover uma certa "inversão de controle", pois esta "dependência externa" pode alterar completamente o comportamento do seu sistema.

No Microsoft Dynamics CRM nós vemos a implementação deste pattern através do mecanismo de Plug-ins.

Quando implementamos a interface IPlugin estamos criando a dependência externa citada na definição do pattern.

Veja o Exemplo Abaixo:

namespace MyPlugins {

public class PluginImplementation : IPlugin {

public void Execute(IPluginExecutionContext context) {
// implementação do seu método;
}
}
}

Após implementar a classe acima e registrá-la no MS CRM o PluginRegistration Tool encarrega-se de criar os registros nas tabelas PluginAssemblyBase, para armazenar o nome do assembly gerado "MyPlugins.dll", e na tabela PluginTypeBase, para armazenar o caminho completo até a classe que implementa a interface IPlugin, no nosso caso MyPlugins.PluginImplementation.
Após a pesquisa dos dados do assembly que você registrou no banco de dados será executado no kernel do MS CRM um trecho de código conforme apresentado nas linhas abaixo:

// O código abaixo executado pelo kernel do MS CRM.

// Criando a instância do plugin registrado pela ferramenta.
IPlugin plugin = (IPlugin) Assembly.Load("MyPlugin.dll").CreateInstance("MyPlugin.PluginImplementation");

// Disparando o método Execute da classe PluginImplementation, criado por você.
plugin.Execute("Instância da interface IPluginExecutionContext");

Com isto temos a "inversão de controle", conforme citado anteriormente, pois neste momento a execução do método "Execute()", que ocorre no kernel do MS CRM, passa a estar totalmente sob seu controle e assim vemos a utilização do pattern Dependency Inection. Simples não é?

Um outra arquitetura que explora muito este pattern e o próprio ASP.NET, aonde temos a possibilidade de fazer inúmeras configurações no web.config e machine.config, como HttpModules, HttpHandler, MembershipProvider, etc.


Se analisarmos bem estamos cercados pelos Design Patterns, só precisamos estar atentos para identificar suas vantagens e a partir daí utilizá-los da melhor forma possível em nossas aplicações.


[]'s


Ricardo Cunha