quinta-feira, 10 de dezembro de 2009

Regras e Boas Práticas para Nomenclatura no .Net


Já faz um tempo que não atualizo o blog. Graças a Deus as coisas estão se acalmando e agora eu tenho mais tempo vago.

Vou falar um pouco hoje sobre as nomenclaturas e suas regras e boas práticas no dotNet que é algo muito importante na programação que facilita o entendimento do código.

Padrão

Seguir um padrão é uma boa prática de programação, pois como eu disse, facilita e muito o entendimento do código. Mas qual padrão escolher? Então se você programava em VB6, C++, Delphi ou Java certamente existia um padrão, ou você mesmo pode ter inventado um padrão.

Bem, eu aconselho utilizar o padrão do próprio dotNet. Sim existe um padrão que faz parte das boas praticas do dotNet. Você pode observar o próprio framework onde há várias bibliotecas e tudo segue um padrão. A importância de se programar no padrão da sua linguagem é que fica “compatível” com a biblioteca dela, por isso não é legal utilizar o padrão do Java no dotNet ou vice-versa.

Estilos de Escrita

Antes de mostrar as regras, vamos conhecer os três estilos de escrita (casing styles) de identificadores no dotNet:

Caso Camelo/Camel Casing

No caso camelo a primeira letra do identificador é minúscula, caso o identificador é formado por mais palavras, as letras iniciais do restante das palavras é iniciado com letra maiúscula.
Exemplos: casoCamelo, soma, minhaVariavelNumerica .

Caso Pascal/Pascal Casing

No caso Pascal a primeira letra do identificador é maiúscula e o restante da palavra é minúsculo, assim como o caso camelo, caso o identificador seja formado por mais de uma palavra elas serão iniciadas com letra maiúscula.
Exemplos: CasoPascal, Soma, DesenhaRetanguloArredondado, ToString.

Uppercase:

Nesse caso todas as letras são maiúsculas. É utilizado apenas em siglas.
Exemplos: UI, IO

Onde Utilizar Cada Estilo

Variáveis Locais, Parâmetros e Campos Privados - Caso Camelo

O caso camelo é usado em nomes de variáveis locais, campos privados (variável no escopo da classe) e parâmetros.

Não se usa nunca uma variável publica ou protegida(protected) no escopo da classe, é utilizado property para encapsular e dar acesso publico ou protegido.

Ao nomear uma variável tente deixar o nome mais legível possível, legibilidade acima de abreviação, mesmo que fique um pouco grande o nome. Se for usar siglas tem que utilizar algo que as pessoas entendam, que seja natural.

Ao nomear uma variável ou um método evite colocar o tipo no nome mas priorize o sentido. Por exemplo ao invés de declarar "salarioDec" deixe apenas "salario" dessa maneira estará priorizando o sentido.
Outro exemplo é o método "GetLenght" que é melhor que "GetInt" ou "GetLenghtInt".
GetLenght poderia retornar basicamente qualquer coisa, poderia ser uma string "grande"/"medio"/"pequeno" ou um enum e etc. No fundo o tipo é o menos importante em um nome, você descobre ele passando o mouse em cima ou de outras maneiras, mas o sentido é realmente importante, você sabe que está retornando um tamanho.

Não utilize notação húngara onde as variáveis começam com um prefixo muitas vezes simbolizando um tipo.
Exemplo iRetorno, strNome.
Nomes de componentes é legal colocar prefixos("btnOk", "tbxNome") facilita e muito o entendimento do código, renomeie os controles que você for utilizar no código, se for um label que vai ficar parado na tela não há porque mudar o nome. A intenção é deixar o código mais fácil de entender.

Não use separadores(underlines ou hífens) para separar duas palavras em um identificador, o caso pascal e o camelo suprem essa necessidade deixando as primeiras letras das palavras em maiúscula.

Classes, Structs, Enums e Interfaces - Caso Pascal

Todos os tipos são utilizados o caso pascal.

Lembrando que quando você cria uma classe, alem de ser um tipo de dado ela simboliza um entidade do mundo real definida por atributos e comportamento. Quando for nomear uma classe que simboliza uma única entidade não coloque o nome no plural.
Exemplo: Classe Clientes contem atributos como nome e idade.
A classe Clientes simboliza um único cliente, então não deve colocar ela no plural. Apenas uma instancia de uma coleção de Cliente(List<Cliente>) poderia nomear como clientes ou uma nova classe ClienteCollection.

Não utilize prefixos nas classes, enums ou structs. Exemplo ClsPessoa, CPessoa.
Apenas interfaces devem começar com o prefixo "I", exemplo: IInterface, ICompareble. É a única exceção da regra.

Os membros do Enum são caso pascal também. Exemplo: Cores.Vermelho, Cores.Amarelo.

Em classe herdada nomeia-se usando o nome da classe base como sufixo. Exemplo: ClienteException, EsmeraldinoEventArgs.

Métodos, Property, Eventos e Namespaces - Caso Pascal

Todos eles são caso pascal e tudo que for publico ou protegido(protected).

Ao nomear um método tente mostrar a ação dele, pois normalmente métodos executam ações. Não de nomes que revelam detalhes da implementação, deixe mais abstrato possível o nome de maneira que qualquer desenvolvedor entenda.

No primeiro tópico há dicas que servem para métodos.

Nomeie a propriedade usando um adjetivos ou substantivo, normalmente elas encapsulam uma característica da classe.

Não faça propriedade com o mesmo nome de um método Get/Set. Exemplo: Propriedade Idade e métodos GetIdade e SetIdade.
Isso irá causar confusão no desenvolvedor.

Em propriedades booleanas coloque os nomes afirmativos, exemplo: IsNew ao invés de IsNotNew.
Você pode colocar prefixos como Is, Can e Has em propriedades booleanas.

Ao nomear um evento alem de demonstrar sua ação, de uma noção de tempo se é antes ou depois. Exemplo: IdadeChanging(antes) e IdadeChanged(depois).

Crie os eventos com o EventHandler de modo que a assinatura fique no padrão "sender" que é o objeto que disparou o evento e "e" que é o argumento, derivado da classe EventArgs.

Considerações Finais e Referências

Espero ter esclarecido esses pontos que eu considero de extrema importância no desenvolvimento de um software. Essas praticas ajudam a você mesmo a entender seu código e dar manutenção em um futuro não muito distante.

Verifique as referências abaixo, há mais detalhes.

MSDN Guidelines for Names -

http://msdn.microsoft.com/en-us/library/ms229002.aspx


MSDN Capitalization Conventions -
http://msdn.microsoft.com/en-us/library/ms229043.aspx

MSDN General Naming Conventions -
http://msdn.microsoft.com/en-us/library/ms229045.aspx

MSDN Names of Classes, Structs, and Interfaces -
http://msdn.microsoft.com/en-us/library/ms229040.aspx

Tiago Esmeraldino

quarta-feira, 21 de outubro de 2009

Visual Studio 2010 Beta 2 Disponível para Todos

Novos bits foram liberados na segunda para quem tem assinatura MDSN e hoje (21/10) é a vez do grande publico.
Há muitas novidades na IDE, Framework e linguagens. Inclusive o Visual Studio mudou o logo(finalmente), agora da para perceber que é um simbolo de infinito hehehe.

Você pode saber de tudo acessando esse link do MSDN.

Clique aqui para baixar o Visual Studio Beta 2.

Eu já estou baixando a versão Ultimate...
Até a Mais

sábado, 10 de outubro de 2009

Maneiras de Verificar se uma String é Vazia

No .Net existe algumas maneiras de testar se uma string é vazia, mas talvez o mais conhecido seja utilizando os operadores de igualdade '='(VB) ou '=='(C#).
Ex:
if (str == "") (...)

Essa é clássica e funciona graças a sobrecarga de operadores do .Net, caso contrário estaríamos comparando endereços de memória.

O Método Equals

Outra alternativa é o método Equals que é o mais comum nas linguagens orientada a objetos para comparar um objeto qualquer.
Ex:

if (str.Equals("")) (...)

Esse método é mais eficiente do os operadores quando o resultado da comparação é falsa, no entanto quando o resultado é verdadeiro os operadores se saem melhor, a conclusão é não tem muita diferença entre as duas maneiras.

A Propriedade Length

A propriedade Lenght retorna o tamanho da string, então basta verificar se ela é igual a 0.
Ex:

if (str.Lenght == 0) (...)

Esse maneira é realmente eficiente, porem ela não é muito legível e assim como o Equals estamos invocando um membro de um objeto e se ele for nulo pode causar um exceção ou aumentar a complexidade do código para checagem da string nula.

O Método IsNullOrEmpty

A ultima maneira é utilizando o método IsNullOrEmpty da própria classe string.
Ex:

if (String.IsNullOrEmpty(str)) (...)

Essa maneira é 2 ou 3 vezes mais eficiente do que o operador de igualdade ou o método Equals, é equivalente ao Lenght porem ele não vai disparar uma exceção se a string for nula.

 Conclusão

Sem dúvida a melhor maneira de testar se uma string é vazia é utilizando o método IsNullOrEmpty por causa da velocidade e segurança.

Claro que uma testadinha com operador não vai dar diferença nenhuma, mas acho que em uma aplicação o que vale é o conjunto da obra e é bom saber que cada tijolinho está colocado de maneira eficiente.

Até Mais,
Tiago Esmeraldino

quinta-feira, 1 de outubro de 2009

Criando e Consumindo Serviços no Silverlight - Parte 2


Introdução

Demorei mais do que eu pensava para escrever, estou tendo bastante correria no serviço graças as mudanças nas leis sobre PAF-ECF.
Mas isso é assunto para outro post talvez...

Voltando ao assunto, no post anterior eu demonstrei como se cria um serviço para ser utilizado no Silverlight. Agora vamos utiliza-lo!

Criando um Aplicativo Silverlight

Vamos criar um projeto silverlight no Visual Studio:


Figura 1 - Criando um Projeto Silverlight

Figura 1 - Criando um Projeto Silverlight

Apos criado o projeto vamos abrir (se já não estiver aberto) o arquivo MainPage.xaml, vamos colocar um TextBlock e um botão para testar o serviço.
Você pode fazer isso alterando o código XAML ou pelo Expression Blend.

Código XAML

<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
        <TextBlock x:Name="lbResposta" Height="20" Width="100" Text="Resultado: "/> 
<Button x:Name="btAcessar" Height="20" Width="100" Content="Acessar"/>
</StackPanel>
</Grid>

Referenciando o Serviço

Vamos referenciar o serviço, você pode clicar com o botão direito no seu projeto e ir no Add Service Reference.

Figura 2 - Acessando o Menu
Figura 2 - Acessando o Menu

Uma tela abrirá, coloque o endereço do seu serviço em 'Address' e click em 'Go'.
Apos ele encontrar o serviço você pode definir um nome para o namespace e confirmar clicando em 'Ok' como ilustrado na imagem abaixo.
Esse processo é igual para uma aplicação desktop.

Figura 3 - Referenciando o Serviço

Figura 3 - Referenciando o Serviço

Crie um método para o evento click do botão, você pode fazer com o Expression Blend ou por código xaml que o Visual Studio ajuda.

Figura 4 - Criando o Evento do Botão por XAML

Figura 4 - Criando o Evento do Botão por XAML

Instanciando um Serviço e Vinculando Eventos

No MainPage.cs vamos declarar o serviço como um atributo(no escopo da classe), e no construtor vamos instanciar o serviço. No evento click do botão vamos chamar o método do serviço. A classe ficará assim:

C#

public partial class MainPage : UserControl
    {
        private ServiceReference1.MeuServicoClient ws;

        public MainPage()
        {
            InitializeComponent();
            ws = new ServiceReference1.MeuServicoClient();
        }

        private void btAcessar_Click(object sender, RoutedEventArgs e)
        {
            ws.DizOiAsync();
        }
    }

VB.Net

Public Partial Class MainPage
    Inherits UserControl
    Private ws As ServiceReference1.MeuServicoClient
    
    Public Sub New()
        InitializeComponent()
        ws = New ServiceReference1.MeuServicoClient()
    End Sub
    
    Private Sub btAcessar_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ws.DizOiAsync()
    End Sub
End Class

Você percebeu que o método 'DizOiAsync' não retorna nada?
Os métodos do web service executam de modo assíncrono, o programa não espera ele executar para continuar rodando (isso é ótimo).

Na instancia do serviço('ws') há um evento 'DizOiCompleted', apenas precisamos inscrever o método nesse evento e receber o resultado.
Quando ele receber uma resposta do serviço ele irá disparar esse evento.

Para inscrever o evento precisamos de um método que satisfaça a assinatura(cabeçalho) do evento. Essa assinatura segue o padrão dos parâmetros 'object' e o 'EventArgs', no caso do EventArgs há um especializado do serviço que é o DizOiCompletedEventArgs, esse EventArgs tem uma propriedade Result que é a resposta do serviço.

Resumindo o método deve ter uma assinatura assim '(objet, DizOiCompletedEventArgs)', depois é só vincular como mostra o código abaixo:

C#

public MainPage()
{
 //(...) código já implementado do construtor da classe
 ws.DizOiCompleted += new EventHandler<ServiceReference1.DizOiCompletedEventArgs>(ws_DizOiCompleted);
}

private void ws_DizOiCompleted(object sender, ServiceReference1.DizOiCompletedEventArgs e)
{
 lbResposta.Text = e.Result;
}

VB.Net

Public Sub New()
    '(...) código já implementado do construtor da classe
    AddHandler ws.DizOiCompleted, AddressOf ws_DizOiCompleted
End Sub

Private Sub ws_DizOiCompleted(ByVal sender As Object, ByVal e As ServiceReference1.DizOiCompletedEventArgs)
    lbResposta.Text = e.Result
End Sub

Agora basta executar a aplicação e ver o resultado.

Detalhes

Qualquer exceção que ocorrer dentro do web service retornará uma mensagem 'The remote server returned an error: NotFound.', por esse motivo é bom tratar as exceções dentro do serviço, pois essa mensagem não quer dizer nada.

Outro detalhe é que para executar o silverlight consumindo os serviços fora do servidor(debuggar por exemplo) precisa de um arquivo de configuração o Cross Domain Policy na raiz do seu servidor, você pode ver detalhes nesse post no blog do Tim Heuer. É bem simples.

Até a próxima,
Tiago Esmeraldino

domingo, 20 de setembro de 2009

Criando e Consumindo Serviços no Silverlight - Parte 1


Intrudução

Desde que o Silverlight 2 foi lançado eu comecei a estudar essa tecnologia. O Silverlight permite criar aplicações ricas na internet, ou seja, aplicações que se aproximam muito de uma desktop. Antes disso eu fazia aplicações com ASPX, mas só ASPX não era suficiente, tinha que integrar com Ajax/JScript para poder criar uma aplicação que funcionasse de maneira intuitiva para o usuário.

Foi ai que surgiu a ideia de usar o Silverlight 2, mas para uma aplicação funcionar tem que ter o famoso CRUD(Create, Retrieve, Update e Delete), em outras palavras o usuário tem que inserir, buscar, alterar e deletar dados e esses dados tem que ser persistentes.
Minha maior dificuldade no inicio foi justamente criar um serviço para fazer conexão com o banco e consumi-lo no Silverlight para criar meu CRUD.

Nesse tutorial vou ensinar a criar um web service em um projeto web comum e configurá-lo para que você use ele na sua aplicação do Silverlight 2 ou 3.

Esse artigo é para quem já tem um servidor e não sabe criar um web service para o Silverlight ou está tendo problemas para fazer funcionar.

Criando o WebSite

Vou criar um projeto do tipo website em uma solução separada do projeto do Silverlight, talvez você já tenha um projeto website pronto e você queira colocar o serviço nele, fica ao seu critério.

Para criar o projeto WebSite pelo menu:
File->New WebSite-> ASP.Net WebSite

Figura 1 - Criando o Web Site
Figura1 - Criando o Web Site

Damos um nome para o projeto e escolhemos também a linguagem como mostra a figura 1, eu irei disponibilizar o código para C# e VB.Net.

Criando o Web Service no WebSite

Para criar o serviço pelo menu:
WebSite->Add New Item->Silverlight-Enabled WCF Service

Figura 2 - Criando o Serviço no projeto Web Site
Figura2 - Criando o Serviço no projeto Web Site

Esse tipo de serviço é muito parecido com o tradicional ASMX que talvez você já esteja habituado. Tudo que você faz com o ASMX é possível fazer com o WCF.

O serviço fica divido em dois arquivos, um com a extensão '.svc' que fica na raiz e a classe(.cs/.vb) que fica na pasta App_Code, como mostra na figura 3, logo abaixo.

Figura 3 - Solution Explorer
Figura 3 - Solution Explorer

Apos criarmos o serviço ele vem com um método de exemplo que é o DoWork. Todo método que você deseja utilizar na sua aplicação deve ter o atributo 'OperationContract', caso contrario ele não será visto por sua aplicação.
Bem vamos criar um novo método para testar nosso serviço.

CSharp

[OperationContract]
public string DizOi()
{
 return "Hello World";
}

VB.Net

<OperationContract()> _
Public Function DizOi() As String
 Return "Hello World"
End Function

Ainda Falta Alguma Coisa...

Esse é o ponto chave, o pulo do gato, a risada da hiena, o rugido do leão... hehehe
Se você rodar no localhost irá funcionar perfeitamente mas talvez no seu servidor não rode!
Um jeito de você testar rapidamente se o seu serviço está ok é acessando via browser, exemplo: "www.meusite.com/meuapp/servico.svc".
Você pode se deperar ou já está se deparando com um erro semelhante a esse:

Server Error in '/MeuWebApp' Application.

This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
Parameter name: item

Implementando a Factory

Bem, falta implementar a factory que é bem simples (quando você já tem um código pronto hehe).
Adicione uma classe no seu projeto web como ilustra a figura abaixo:

Figura 4 - Adicionando uma Classe no Projeto
Figura 4 - Adicionando uma Classe no Projeto

Nessa classe você colocará o código abaixo:

CSharp

using System.ServiceModel.Activation;
using System.ServiceModel;
using System;

public class MeuServicoFactory : ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        // Coloque o endereço do seu servico na string abaixo
        Uri webServiceAddress = new Uri("http://www.SEUSITE.com/MeuServico.svc");
        ServiceHost webServiceHost = new ServiceHost(serviceType, webServiceAddress);
        return webServiceHost;
    }
}

VB.Net

Imports Microsoft.VisualBasic
Imports System.ServiceModel.Activation
Imports System.ServiceModel


Public Class MeuServicoFactory
    Inherits ServiceHostFactory

    Protected Overloads Overrides Function CreateServiceHost(ByVal serviceType As Type, ByVal baseAddresses As Uri()) As ServiceHost
        ' Coloque o endereço do seu serviço na string abaixo
        Dim webServiceAddress As New Uri("http://www.SEUSITE.com/MeuServico.svc")
        Dim webServiceHost As New ServiceHost(serviceType, webServiceAddress)
        Return webServiceHost
    End Function
End Class

Coloque o endereço do seu serviço(.svc) no construtor da Uri como ilustrado no código acima.

Agora falta referenciar a factory no serviço, para isso abra o arquivo '.svc', você encontrará definições do seu serviço.
Depois da especificação do 'Service="MeuServico"' coloque uma especificação para o factory colocando o nome da sua classe factory 'Factory="MeuServicoFactory"'.

Seu '.svc' ficará assim:

<%@ ServiceHost Language="C#" Debug="true" Service="MeuServico"Factory="MeuServicoFactory" CodeBehind="~/App_Code/MeuServico.cs" %>

Testando o Serviço no Navegador

Com a factory criada e marcada no '.svc' vamos testar, copie o seu web site para o servidor e acesse ele no navegador. Se o seu web service estiver "saudavel" aparecerá no navegador dois exemplos de como usar ele na aplicação, como a imagem abaixo.

Figura 5 - Serviço Funcionando no Browser
Figura 5 - Serviço Funcionando no Browser

No Próxima Parte

Na segunda parte desse tutorial iriei ensinar como consumir o serviço no Silverlight.
Espero ter ajudado já nessa primeira parte a fazer o serviço funcionar corretamente no servidor, dessa maneira ele está preparado para ser referenciado na aplicação Silverlight.

Até breve,
Tiago Esmeraldino

quinta-feira, 17 de setembro de 2009

DICA: Ferramenta Para Converter Código VB.Net/C#

Acho que nem todos sabem mas existe ferramentas que convertem código C# para VB.Net e vice-versa.

A melhor que eu encontrei é essa online gratuita:
http://www.developerfusion.com/tools/convert/csharp-to-vb/

Ela é beseada na SharpDevelop que é uma IDE gratuita para .Net, uma solução para quem não gosta do Visual Studio.

Talvez você não quer converter seus projetos, mas as vezes procuramos códigos na Web e estão em C# ou em VB.Net e a solução mais rápida para converter o código é com essa ferramenta.

Fica a dica.

Até a próxima,
Tiago Esmeraldino

quinta-feira, 10 de setembro de 2009

Prefiro C# do que VB.Net - Parte 3


Introdução

Nessa ultima parte irei abordar uns dos principais atrativos da sintaxe do C# e vou comentar um pouquinho sobre o futuro muito próximo das duas linguagens.

Quebrando _
    Linha

A sintaxe do VB.Net trabalha com quebras de linha para simbolizar o fim de uma instrução, diferente de outras linguagens que utilizam o ponto e virgula. Isso significa que você não pode quebrar uma linha sem o underline que acaba deixando o código um pouco estranho.

Isso não seria tão ruim se boa parte das palavras chaves do VB.Net não deixasse o código grande, e isso gera uma necessidade ainda maior de quebrar as linhas.

O recurso mais aplaudido do VB.Net 10 sem duvida é a possibilidade de quebrar o código em alguns pontos sem o underline, e esses pontos são uteis o que é muito bom. Mas enquanto não chega 2010 e não atualizamos nossas aplicações para o framework 4.0 isso continua sendo um atrativo para eu programar em C#.

Como eu disse, as palavras chaves do VB.Net é tudo grande, até para você dizer que a variável é nula é preciso de um 'Nothing' no lugar do'null'. Isso
porque a sintaxe do VB.Net é mais próxima do inglês o que deve ajudar os iniciantes, se eu abrir um 'If' preciso do 'End If' e na maioria das vezes é 
tudo assim(function, sub, class e etc).

Isso deixa o código um pouco poluído, alem do mais apesar de ser intuitivo ninguém precisa colocar o 'End <comando>' porque a IDE ajuda de todos os jeitos e na maioria das vezes basta um enter para ela escrever o resto para você.  Por outro lado você consegue saber rapidamente onde abre e onde fecha cada comando.

Um exemplo de um método simples:

Public Function Soma(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
 Dim ret As Integer = num1 + num2
 Return ret
End Function

No C#:

public int Soma(int num1, int num2) 
{
 int ret = num1 + num2;
 return ret;
}

Nesse pequeno exemplo mostra que no C# não precisa das palavras chaves na assinatura do método: function, as, byval. E na declaração não precisa do 'Dim' e 'As'.
Não vou listar mais comparações porque tem esse site cheio de comparações.

Quando é um método com vários parâmetros é bom pensar se esses parâmetros não deveriam estar em  uma classe, mas quando não tem como criar uma classe o VB.Net se sai muito ruim. A solução é comprar um monitor widescreen ou utilizar as quebras com underline, a segunda opção é mais viável hehehe.

O Futuro Não Muito Distante

Há funcionalidades legais que só tem no VB.Net e tem outras que só tem no C#. Na próxima versão o C# 4.0 virá com parâmetros nomeados e opcionais, late binding e o VB.Net 10 alem da quebra de linha terá auto propertys. Funcionalidades interessantes que hoje é um atrativo de cada linguagem mas no futuro será tudo(quase) igual, só mudando a sintaxe(que é o que eu gosto no C#).

Até Mais,
Tiago Esmeraldino