Estilo de programação

Postado por Carlos Fernando Sylverio | Postado em Orientação a Objetos, Programação | Postado em 24-06-2009

1

Não é nada de outro mundo, mas totalmente fundamental para o desenvolvimento de software em equipe. Estilo são definições de como escrever o código fonte, em outras palavras, padrões de nomenclatura para nomes e declarações de variáveis, atributos, métodos, classes, etc.

Para isso podemos seguir algumas convenções (como em Java e C#.Net), ou criar um definições de estilo com apropria equipe em questão.

Vantagens ao usar estilo

Quando se esta desenvolvendo em equipe, o código deve ser compreendido por todos os membros. O estilo de programação tem como função auxiliar a equipe escrever código de modo único, assim é de fácil compreenção os códigos criados por outros menbros.

Complementação do estilo

Mais meu habito que propriamente do estilo, é ter um cuidado especial ao se definir nomes de objetos, métodos, atributos, variáveis, entre outros. A correta nomeação dos elementos no código ajuda a diminuir o hiato entre o código e mundo real, e assim como estilo de programação, também tornar mais fácil sua compreensão.

Exemplos do dia a dia

Recentemente estive envolvido em um projeto de uma aplicação antiga. Não havia na empresa mais nenhum desenvolvedor que criou a aplicação e precisávamos implementar algumas melhorias. Ao começar a implementar as melhorias, me deparei com algumas variáveis chamada X, Y, item. E perdi horas tentando compreender o que significa X, Y e item.

Conclusão

Para exemplificar esses conceitos, criei 2 aplicações iguais, ambas em Java, porem o primeiro está totalmento sem estilo e o segundo com um estilo que normalmente sigo. Compare e tire suas próprias conclusões:

Aplicação sem estilo

public class XyZ {
	public String no;
	public int id;
}
import java.util.ArrayList;
 
public class XyZs extends ArrayList{
	private static final long serialVersionUID = 1L;
}
import java.util.Iterator;
 
public class Application {
 
	public static void main(String[] args) {
 
		XyZs xxs = new XyZs();
 
		xxs.add(Cria("Sergio", 20));
		xxs.add(Cria("Rafael", 24));
		xxs.add(Cria("Frank", 22));
 
		ImprimeLista(xxs);
	}
 
	public static XyZ Cria(String n, int i) {
 
		XyZ x = new XyZ();
		x.no = n;
		x.id = i;
 
		return x;
	}
 
	public static void ImprimeLista(XyZs g){
		System.out.print("==== Lista de Amigos ==== \n");
 
		for (Iterator i = g.iterator(); i.hasNext();) {
			XyZ a = (XyZ) i.next();
			System.out.print("Nome: " + a.no + " idade: " + a.id + "\n");
		}
	}
 
}

Aplicação com estilo

public class Amigo {
	public String nome;
	public int idade;
}
import java.util.ArrayList;
 
public class Amigos extends ArrayList{
	private static final long serialVersionUID = 1L;
}
import java.util.Iterator;
 
public class Application {
 
	public static void main(String[] args) {
 
		// cria lista de amigos
		Amigos amigos = new Amigos();
 
		// adiciona amigo a lista
		amigos.add(CriaAmigo("Sergio", 20));
		amigos.add(CriaAmigo("Rafael", 24));
		amigos.add(CriaAmigo("Frank", 22));
 
		ImprimeLista(amigos);
	}
 
	public static Amigo CriaAmigo(String nome, int idade) {
 
		Amigo ret = new Amigo();
		ret.nome = nome;
		ret.idade = idade;
 
		return ret;
	}
 
	public static void ImprimeLista(Amigos amigos){
		System.out.print("==== Lista de Amigos ==== \n");
 
		for (Iterator i = amigos.iterator(); i.hasNext();) {
			Amigo amigo = (Amigo) i.next();
			System.out.print("Nome: " + amigo.nome + " idade: " + amigo.idade + "\n");
		}
	}
 
}

Perceptível a diferença, não?

Links Complementares:

Não encontri nenhum artigo de estilo de Java, assim que eu encontrar eu posto aqui. Enquanto isso podemos ver a API do Java e tirar nossas conclusões de como escrever em Java com um estilo bem parecido.

Até mais… ;-)

Vídeo interessante

Postado por Carlos Fernando Sylverio | Postado em Orientação a Objetos, Programação, Tecnologia | Postado em 12-03-2009

0

Pessoal, encontrei um vídeo com uma palestra sobre Domain Driven Design, no Blog da Localweb.

Achei bem legal pois ele completa um pouco o post anterior.

Enjoy!

Generalização Especialização Herança

Postado por Carlos Fernando Sylverio | Postado em Orientação a Objetos, Programação, UML | Postado em 29-01-2009

0

Olá pessoal, estive de férias e passei um bom tempo sem escrever, mas agora descançado, não há mais desculpas.

Fiz uma breve descrição sobre generalização, especialização e herança, devido a um pedido do último post e montei um pequena aplicação para exemplificar o assunto.

Conceito

Podemos dizer que generalização é o agrupamento de objetos ou elementos com características comuns em um modelo ou sistemas, é uma descrição mais geral sobre o objeto referente.

E a especialização é processo inverso, é a definição das particularidades de cada objeto ou elemento, são elementos mais consistentes que estendem o elemento genérico.

Dando continuidade ao exemplo citado no último post, casa, galpão, prédio, chamarei a generalização de “Habitação“.

(achei que não foi uma boa escolha esses elementos, prédio, galpão, etc… Para falar de generalização, mas vou utilizá-los para não confundir quem está começando a ver O.O., e manter um pouco de compatibilidade com o post anterior)

Ou seja, todos os elementos, são habitações, porém cada elemento guarda sua característica particular.

O que se ganha com isso?

A utilização de generalização tem dois propósitos:

  • Permitir que a classe base ou subclasse ser usada como variável. E regra é que uma instância da subclasse possa ser usada quando a superclasse é declarada. Com isso possibilitamos a realização de operações polimórficas.
  • Permitir a incrementar as características de um elemento pelas características comuns de seu antecessor. Esta é a chamada de herança.

Herança é a definição da implementação da generalização no código

Já li em alguns livros que o conceito de generalização pode ser utilizada para agrupar características comuns de cada objeto, passando os atributos comuns para o objeto mais genérico. Mas eu discordo desta opinião.

Não há nenhuma vantagem criar um modelo utilizando generalização e especialização se não for para se aproveitar de um dos benefícios comentados acima.

Na verdade estaremos adicionando mais complexidade ao modelo e tornando o código menos escalável.

Prática

Criei um exemplo simples em C#.NET para mostrar como aplicar os conceitos acima.

Para isso no Visual Studio vá em File->New->Project.

Em Templates, escolha Console Application.

Altere o Name para Generalizacao e clique em OK

Agora vá ao projeto (Generalizacao), clique com o botão direito vá em Add->New Item.

Em Templates, escolha Class.

Altere o Nome para Habitação.

Altere o código de para que fique da seguinte forma:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
 
namespace Generalizacao
{
    public abstract class Habitacao
    {
        /// <summary>
        /// Quantidade de tomadas da habitação
        /// </summary>
        private int qtdTomada;
 
        /// <summary>
        /// Obtem a quantidade de tomadas
        /// </summary>
        public int GetQtdTomada()
        {
            return qtdTomada;
        }
 
        /// <summary>
        /// Armazena a quantidade de tomada
        /// </summary>
        public void SetQtdTomada(int value)
        {
            qtdTomada = value;
        }
    }
}

Adiciona ao projeto as classes Casa, Predio e Galpao, e altere o código da seguinte forma:

Casa

1
2
3
4
5
6
7
8
9
10
11
using System;
 
 
 
 
namespace Generalizacao
{
    public class Casa : Habitacao
    {
    }
}

Observação:

Em C#, a sintaxe para herança é a utilização do comando: após o nome da classe seguindo do nome da classe a ser herdada.

Em Java, a sintaxe para herança é o comando extends após nome da classe seguindo do nome da classe a ser herdada.

Predio

1
2
3
4
5
6
7
8
using System;
 
namespace Generalizacao
{
    public class Predio : Habitacao
    {
    }
}

Galpao

1
2
3
4
5
6
7
8
using System;
 
namespace Generalizacao
{
    public class Galpao : Habitacao
    {
    }
}

Pronto. Criamos a estrutura modelada em UML acima.

Agora nossa Solution deve ter a seguinte aparência.

Na classe Program.cs, escreva o seguinte código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
 
namespace Generalizacao
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // Instâncias de casa
            Casa casa = new Casa();
            casa.SetQtdTomada(15);
 
            // Instâncias de prédio
            Predio predio = new Predio();
            predio.SetQtdTomada(300);
 
            // Instâncias de galpão
            Galpao galpao = new Galpao();
            galpao.SetQtdTomada(40);
 
            ImprimirValorDeTomada(casa, "Casa");
            ImprimirValorDeTomada(predio, "Predio");
            ImprimirValorDeTomada(galpao, "Galpao");
        }
 
        private static void ImprimirValorDeTomada(Habitacao habitacao,String tipo)
        {
            Console.WriteLine("{0} tem a seguinte quantidade de tomadas: {1}", tipo, habitacao.GetQtdTomada());
        }
    }
}

Como você deve ter observado, quando estava codificando, o seguinte acontecimento. O intellisense apresentar os métodos codificados na classe Habitação, para todas as subclasses.

Isso é possível devido às classes Casa, Predio e Galpao herdarem da classe Habitação, ou seja, toda a classe que herda de Habitação terá sua característica e comportamento.

Outra coisa que podemos observar nesse exemplo é o método ImprimirValorDeTomada que recebe como parâmetro Habitação, porém é passado Casa, Predio e Galpao.
Toda subclasse pode ser convertida no tipo da superclasse. Nesse método não importa qual é o tipo de habitação e sim se é do tipo habitação.

Observação

Toda subclasse pode ser convertida no tipo da superclasse, porém para o processo inverso é necessário a realização de cast.

Exemplo:

1
2
3
4
5
Casa casa1 = new Casa();
// conversão Implicit
Habitacao hab = casa1;
// conversão Explicit (Cast)
Casa casa2 = (Casa)hab;

Mas pra frente falarei mais sobre generalização.

Carlos Fernando

Como programar com “responsabilidade”

Postado por Carlos Fernando Sylverio | Postado em Análise, Orientação a Objetos, Programação | Postado em 18-11-2008

2

Uma das formas de se projetar objetos de software é pensar em suas responsabilidades. Essas responsabilidades podem se tratar de um pequeno objeto a uma divisão macro do sistema.
Essas responsabilidades devem descrever o que um objeto deve fazer e o que o deve saber.

História do dia-a-dia

Suponhamos que você tenha que entregar um relatório para seu chefe sobre uma fórmula química de um produto de limpeza. Mas você não conhece nada de química.
Fácil, não é?
Você delega esta atividade a um químico, para que ele escreva o relatório da fórmula química para você.
Pronto, sem mistério ou complicação.

Atribuindo responsabilidade

O desenvolvimento de software deve ser tão fácil quando a história acima.
As responsabilidades devem ser atribuídas aos objetos que tem a informação necessária para satisfazer as responsabilidade.
Vejamos o modelo seguinte, qual é o melhor objeto para informar a quantidade de tomadas de um quarto?
Modelo domínio
Sabemos que o Quarto tem conhecimento das suas paredes, e que cada Parede tem o conhecimento da quantidade de suas suas tomadas.
Desta forma a melhor solução para aplicamos a responsabilidade de obter a quantidade de tomadas é através do objeto Quarto, que delega a cada Parede que informe sua quantidade de tomada. Assim a quantidade total de tomadas é a soma das tomadas presente em cada parede.
Diagrama de classe

O método TotalTomadas() do objeto Quarto:

1
2
3
4
5
6
7
8
9
public int TotalTomadas()
{
     int ret = 0;
     foreach(Parede parede in paredes)
     {
          ret += parede.GetQtdTomadas();
     }
     return ret;
}

Para melhorar ainda mais esse trabalho, podemos criar um objeto chamado Paredes que estenda o Array (Collection) de paredes presente no objeto quarto, e criarmos um método GetTomadas() que faça o trabalho da soma das tomadas.
Assim, a nossa lista de Paredes presente no objeto Quarto ficaria com a responsabilidade de obter o total de tomadas de cada item interno e somá-los.
Desta forma o método TotalTomadas() fica assim:

1
2
3
4
public int TotalTomadas()
{
     return paredes.GetTomadas();
}

O método GetTomadas() do objeto Paredes:

1
2
3
4
5
6
7
8
9
public int GetTomadas()
{
     int ret = 0;
     foreach(Parede parede in this)
     {
          ret += parede.GetQtdTomadas();
     }
     return ret;
}

Isso nos permite reaproveitar código, pois se no projeto existisse objetos como Galpão, Prédio, etc. Poderíamos utilizar o mesmo objeto Paredes para ambos (dependendo do contexto), pois certamente, Galpão e Prédio têm paredes. Assim estaríamos evitando a duplicação de código e facilitando sua manutenção.

Classe, Objeto, Instância

Postado por Carlos Fernando Sylverio | Postado em Orientação a Objetos, Programação | Postado em 16-11-2008

1

Várias pessoas ainda se confundem ou não sabem diferenciar o que é uma classe, um objeto ou instância.

Resumidamente podermos dizer que:

Classe é o molde de um objeto.

Objeto é a instância de uma classe.

E instância é uma classe inicializada e alocada na memória do computador.

Classe

A classe é um tipo pré definido pelo usuário. Ela é um molde da representação de um objeto existente na vida real.

Quando codificamos uma classe, atribuímos a ela as características e funções do objeto na vida real, sendo que as características são representadas pelos atributos (o que o objeto contém) e funções pelos seus métodos (o que o objeto faz).

Exemplo de uma classe em C#.NET:

Código em C#

Exemplo de uma classe em Java:

Código em Java

Objeto

Para se criar um objeto é necessário inicializá-lo. Fazemos isso por meio do operador new que invoca o construtor da classe a ser instanciada. Com isso podemos ter múltiplos objetos da mesma classe, cada um assumindo sua característica.

Imagina a classe Carro descrita acima. No mundo real existem vários carros de várias marcas. Representamos isso no código por meio da criação (ou instanciação) de vários objetos.

Exemplo da criação de vários objetos em C#.NET:

Código em C#

Exemplo da criação de vários objetos em Java:

Código em Java

Observações:

Em C#, a palavra reservada new pode ser usada como um operador ou um modificador.

  • new operador – usado para criar um objeto invocando o construtor.
  • new modificador – usado para esconder um membro herdado de uma classe base.

Instância

A instância é a representação da classe durante a execução do programa, pois a classe é a especificação do objeto, ela não pode ser utilizada diretamente.

São as instâncias que permitem o funcionamento do programa através das modificações de atributos e execuções dos métodos. Um objeto existente durante o tempo de execução de um programa é uma instância de uma classe.