Tag Archives: dica

Alterando a convenção de nomenclatura usada no Fluent NHibernate

Recentemente iniciei um projeto na qual decidi utilizar o NHibernate 3.0 e testar o Linq to NHibernate. Posso dizer que estou muito satisfeito com o resultado desta versão e até agora consegui escrever todas as minhas queries usando Linq. Além disso, resolvi também utilizar o Fluent NHibernate já que, das 3 opções que temos, é a que mais me agrada.

Para quem me conhece sabe que eu extremamente chato quanto a nomenclatura de classes, variáveis, tabelas, pacotes etc. Nem sempre consigo achar um nome legal, as vezes demora, por isso prefiro colocar um nome temporário e deixar para melhorar em uma próxima refatoração.

Foi exatamente isso que aconteceu quando comecei a utilizar o Fluent NHibernate (FH) e foi o que me levou a escrever este post. Por padrão, sempre que temos uma relação ManyToMany, como por exemplo Usuário e Grupo, o FH cria uma tabela intermediária e esta recebe o nome de UsuarioToGrupo, ou seja, ela segue o padrão {Tabela1}To{Tabela2}. Muitos de vocês devem ter suas próprias convenções para nomear tabelas, por exemplo nunca utilizar nomes no plural ( eu uso bastante esta ) e também utilizar um underline nas tabelas com relacionamento N-N. Seguindo este padrão, o resultado da tabela seria Usuario_Grupo, na qual eu acho mais legível e limpo.

Caso você tambem goste deste formato e deseja utilizá-lo no Fluent NHibernate, crie uma nova classe que extenda ManyToManyTableNameConvention e faça uma sobrescrita dos métodos GetBiDirectionalTableName e GetUniDirectionalTableName conforme o exemplo abaixo.

public class BetterManyToManyTableNameConvention : ManyToManyTableNameConvention
{
    protected override string GetBiDirectionalTableName(IManyToManyCollectionInspector collection, IManyToManyCollectionInspector otherSide)
    {
        return collection.EntityType.Name + "_" + otherSide.EntityType.Name;
    }

    protected override string GetUniDirectionalTableName(IManyToManyCollectionInspector collection)
    {
        return collection.EntityType.Name + "_" + collection.ChildType.Name;
    }
}

Work complete! Essa foi fácil ein? Adoro frameworks extensíveis :)
Não se esqueça de registrar esta customização ao criar a SessionFactory, se você não sabe como fazer isso, estou colando abaixo um exemplo.

ISessionFactory factory = Fluently.Configure().Database(
    MsSqlConfiguration.MsSql2008.ConnectionString("MY SECRET CONN STRING").Mappings(
    x =>
    {
        x.FluentMappings.AddFromAssemblyOf<User>();
        x.FluentMappings.Conventions.Add<BetterManyToManyTableNameConvention>();
    }
).BuildSessionFactory();

Vale lembra também que este é apenas um exemplo de customização, para maiores opções basta consultar a namespace “FluentNHibernate.Conventions” e procurar a interface ou classe de seu interesse.

Até mais!

Dica #6: Escrevendo testes fluentes


Aqui vai uma dica rápida. Quando comecei a escrever meus primeiros testes automatizados eu tinha algo assim.

int actual = calculadora.Somar(1 +2);
int expected = 3;
Assert.AreEquals(expected, actual);

Após um tempo, comecei a ganhar mais experiência e aprendi algo chamado de Fluent Interfaces. O objetivo desta “técnica” é escrever código que seja fácil de ler. O código acima é fácil, correto? Mas da para melhor, quer ver?

Veja este exemplo aqui.

int actual = calculadora.Somar(1 +2);
Assert.That(actual, Is.EqualTo(3));

Melhorou, não acha? Legibilidade faz parte do Clean Code e Fluent Interfaces é uma excelente técnica que pode te ajudar a deixar seu código mais fácil de ler. Reserve um tempo e procure entender melhor como funciona. Além disso, a partir do C# 3.0 tivemos a adição das Closures que também é outro recurso poderosísimo na busca pela Legibilidade.

Nota: Estes exemplos acima foram construidos com NUnit e já vem pronto, não sendo necessário adicionar dependência para nenhuma outra biblioteca. No caso do MSUnit, eu recomendo o Sharp Tests Ex, que alías também funciona com o NUnit.

É isso ai e até a próxima.

Evitando o excesso de ‘null check’

Que atire uma pedra aquele que ainda não está cansado de ver/escrever código assim:

public Departamento insere(Integer codigo, String descricao) {
    if (descricao == null) || (descricao.equals("")) {
        //faz alguma coisa
    }
}

Poxa, é impossível. Cada desenvolvedor deve escrever isso no mínimo umas 10 vezes por dia. Se você faz isso todo dia, acha um saco e nunca achou uma maneira para resolver esse ‘problema’, eis a solução:

public Departamento insere(Integer codigo, String descricao) {
    //faz alguma coisa
}

Simples não? Problema resolvido.

A documentação deve deixar bem claro que este método não aceita nulo ou vazio no parâmetro ‘descricao’.

NOOOOOOOO! Null Pointer Exception.

NOOOOOOOO! Null Pointer Exception.

Se este método for interno à sua aplicação, fica fácil, você sabe que as classes que irão chamar este método precisam estar escritas de tal maneira que não passe nenhum valor nulo ou vazio, caso contrário, haverá algumas excessões não esperadas.
Se você prestar atenção, ao remover essas verificações de toda a hierarquia de classes, as únicas classes que realmente irão precisar da verificação são as classes que interajem com a interface do usuário.

Agora se seu método estiver exposto em um WebService, isso significa que outros desenvolvedores poderão chamar este método e você não tem controle sobre o que estes desenvolvedores irão passar para o método. Neste caso, ainda assim, deixe o método sem as verificações e faça-as nas interfaces do WebService. Crie pré-condições para seus serviços, deixe claro que o parâmetro descrição deve conter algum valor. Se a condição estiver válida, você pode chamar o método tendo a garantia de que não haverá excessões.

É comum que quando nos deparamos com um erro de NullReferenceException (C#) ou NullPointerException (Java) no log da aplicação, a primeira coisa que fazemos é ir direto na linha que deu erro e adicionar a verificação se é nula apenas para que não ocorra tais erros. Se um valor nulo chegou até ali é porque ele deveria ter parado em algum lugar antes, geralmente na camada entre a interface do cliente e o código de negócio.

Lembre-se do princípio da responsabilidade exclusiva! Não é responsabilidade do método ‘insere’ garantir que os parâmetros estejam válidos.

Além deste caso onde você pode ter problemas com parâmetros nulo, existem lugares em que você faz a verificação de nulo com o retorno de um método, ficando mais ou menos assim:

Departamento depto = dao.insere(1, "Compras");
if (depto != null) {
    //Faz algo
}

E nesses caso, como se comportar? Isso vai ficar para o próximo post, lá eu falo sobre isso e um pattern relacionado, chamado de Null Object Pattern. Até mais!

Edit #1: O post sobre Null Object Pattern é este aqui.

Dica #5: Escondendo teclado no Windows Mobile com C#

Olá a todos,

Neste post vou explicar como remover o teclado dos smartphones que possuem windows mobile. Além disso, vou repassar uma dica de como utilizar esse recurso com maior eficiência, prontos?

Porque eu deveria esconder o teclado?

Talvez você esteja se perguntando isso neste momento, é simples, imagine uma tela onde há apenas botões e nenhum campo para digitar, faz sentido dar ao usuário um teclado que ele não vai usar? É muito mais prático remover o teclado e evitar que ele aperte acidentalmente e deixar apenas o que importa na tela.

Como fazer?

Essas funções que envolvem alterações no core são feitas através de P/Invoke. Basicamente, são chamadas feitas à DLLs do próprio sistema operacional através do C#.

Sem mais delongas, vou colocar aqui uma classe com um método para remover o teclado, e é claro, outro para fazer o teclado aparecer novamente.

public static class Keyboard
{
    [DllImport("coredll.dll")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("coredll.dll")]
    private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);

    [DllImport("coredll.dll")]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private static void SetSipButton(bool show)
    {
        IntPtr hSipWindow = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
        if (hSipWindow != IntPtr.Zero)
        {
            IntPtr hSipButton = GetWindow(hSipWindow, 5);
            if (hSipButton != IntPtr.Zero)
                ShowWindow(hSipButton, (show) ? 1 : 0);
        }
    }

    public static void Hide()
    {
        SetSipButton(false);
    }

    public static void Show()
    {
        SetSipButton(true);
    }
}

Para usar é muito fácil. Quer esconder o teclado? Basta escrever:

Keyboard.Hide();

E agora você quer fazer o teclado voltar ao normal?

Keyboard.Show();

Difícil? :}

Agora há um problema, se você colocar isso em todo formulário que você for fazer, você vai repetir este código x vezes, onde x é a quantidade de formulários que você possui.
No coméco eu disse que eu daria uma dica, e a dica é para resolver isso.

Dica

Crie dois formulários que servirão de base. Chame um de KeyboardForm e outro de NoKeyboardForm, faça com que ambos formulários herdem de Form.

No formulário KeyboardForm coloque o código para MOSTRAR o teclado, no formulário NoKeyboardForm coloque o código para ESCONDER o teclado.

Toda novo formulário que você criar, ao invés de herdar de Form (padrão), faça ele herdar de KeyboardForm caso sua tela tenha necessidade de um teclado, caso contrário, herde de NoKeyboardForm.

Simples, elegante, eficiente, e como diria o Steve Jobs, “amazing”, “incredible”, “awesome”, “great”.

Abaixo estou deixando um pacote com uma solução que eu fiz no Visual Studio 2008 com exemplos de uso. É só baixar, abrir e executar.

Clique aqui para fazer o download de 'Removendo teclado no Windows Mobile' (40.28 kB)

Espero ter ajudado.

Sharing Buttons by Linksku