VB .NET - Programação Orientada a Objetos (em 10 lições práticas) - IX


VB .NET é uma linguagem orientada a objetos.

Nesta aula vamos comparar herança com composição, analisar seus fundamentos e saber decidir quando usar os recursos.

- Herança versus Composição - IX

Nesta aula você vai aprender a :

Objetivo: Apresentar os conceitos de herança e composição apresentando seus recursos e comparando-os de forma a saber decidir qual usar em determinada situação.

Recursos usados : Visual Studio 2012 Express for Windows desktop

Nota: Neste momento já se encontra disponível a versão 2013 : http://www.microsoft.com/visualstudio/eng/2013-downloads

É importante salientar que a ferramenta usada é gratuita, não possui restrições sendo totalmente funcional. Ao fazer o download da ferramenta você também pode baixar o pacote de idioma para localizar o produto para a língua portuguesa.

Problema: Você precisa aprender herança e composição, conhecer seus recursos e saber qual utilizar em determinado cenário.

Conceitos Básicos - Herança

O paradigma da Orientação a objetos - OO - traz muitos conceitos novos e, para quem vem do paradigma procedural usando as linguagens estruturadas e do desenvolvimento orientado ao banco de dados, às vezes muitos desses conceitos podem não ser bem compreendidos.

O termo Programação procedural (ou programação procedimental) é as vezes utilizado como sinônimo de Programação imperativa (Paradigma de programação que especifica os passos que um programa deve seguir para alcançar um estado desejado), mas o termo pode se referir a um paradigma de programação baseado no conceito de chamadas a procedimento. Procedimentos, também conhecidos como rotinas, sub-rotinas, métodos, ou funções (que não devem ser confundidas com funções matemáticas, mas são similares àquelas usadas na programação funcional) simplesmente contém um conjunto de passos computacionais a serem executados. Um dado procedimento pode ser chamado a qualquer hora durante a execução de um programa, inclusive por outros procedimentos ou por si mesmo.
(fonte : http://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_procedural)

Apenas para ilustrar, abaixo temos uma tabela comparando as características básicas do paradigma OO e do procedural:

Programação Orientada a Objetos Programação Estruturada
Métodos Procedimentos e funções
Instâncias de variáveis Variáveis
Mensagens Chamadas a procedimentos e funções
Classes Tipos de dados definidos pelo usuário
Herança -
Polimorfismo

Se você quer construir um código limpo , legível , escalável e reutilizável usando os conceitos da OO terá que ter uma compreensão sólida dos principais conceitos deste paradigma.

Como o C# e VB .NET são linguagens Orientada a Objetos(OO), podemos usá-las para criar projetos dentro do paradigma OO.

Esta aula procura focar dois mecanismos básicos usados para reutilizar código muito utilizados na programação orientada a objetos (POO) : a herança e a composição.

Qual seria melhor ?   Usar composição ou usar herança ?

Uma rápida revisão dos conceitos

1- Herança

Exemplo:

Pessoa - classe Pai, classe Base ou Super Classe
  • PessoaFisica - classe Filha ou sub classe
  • PessoaJuridica - classe Filha ou sub classe

- A classe Pessoa é a classe genérica;
- As classes PessoaJuridica e PessoaFisica são especializações;

- PessoaFisica É uma pessoa;
- PessoaJuridica É uma pessoa;

Implementação VB .NET :

Namespace Herança

Public Class Pessoa
     Private nome As String
     Private Endereco As String      
End Class

Public Class PessoaFisica
         Inherits Pessoa

    Private CPF As String
    Public Sub New()
    End Sub
End Class

Public Class PessoaJuridica
      Inherits Pessoa

     Private CNPJ As String
     Public Sub New()
     End Sub
End Class

End Namespace

VB .NET

1- Composição

Exemplo

Pedido - Classe que contém uma instância da classe Itens;

- Um pedido TEM UM Item;

Implementação VB .NET:

Public Class Pedido
	Private i As Itens
	Public Sub New()          
    		i = New Itens()
	End Sub
End Class

Public Class Itens
	Public Sub New()
	End Sub
End Class

Resposta : Herança ou Composição

Em geral usar composição traz mais vantagens do que utilizar herança.

Os projetos tendem a ser mais simples e reutilizáveis em se favorecendo a composição ao invés da herança.

Na verdade a herança deve ser usada com cuidado e apenas em algumas situações.

Estranhou a resposta ???  

Você achava que herança era o supra sumo dos recursos do arsenal das linguagens Orientada a Objeto ??

Se você pensava assim estava enganado...

Então senta que o leão é manso...

Obs: Lembrando que nem a linguagem C# nem a VB .NET suportam herança múltipla; assim uma classe pode herdar de apenas uma única classe.

Ah!! Outro detalhe, eu estou considerando apenas herança de implementação e não estou entrando em detalhes em herança de Interface. Ok ?

Mas porque devemos mesmos dar preferência à composição e não a herança ?

Usando herança:

1- Ao usar herança estamos violando um dos pilares da orientação a objetos: o encapsulamento, visto que os detalhes da implementação da classe Pai são expostos nas classes Filhas;
2- Ao usar herança estamos violando um dos princípios básicos das boas práticas de programação :
manter o acoplamento entre as classe fraco, visto que as classes filhas estão fortemente acopladas à classe Pai e alterar uma classe Pai pode afetar todas as classes Filhas;
3- As implementações herdadas da classe Pai pelas classes Filhas
não pode ser alteradas em tempo de execução;

Usando composição :

1- Os objetos que foram instanciados e estão contidos na classe que os instanciou são acessados somente através de sua interface;
2- A composição pode ser definida dinamicamente em tempo de execução pela obtenção de referência de objetos a objetos de do mesmo tipo;
3- A composição apresenta uma
menor dependência de implementações;
4- Na composição temos cada classe focada em apenas uma tarefa (princípio SRP); - veja o artigo - 
SRP - O princípio da responsabilidade única - Macoratti.net
5- Na composição temos um
bom encapsulamento visto que os detalhes internos dos objetos instanciados não são visíveis;

Percebemos que a herança viola dois conceitos básicos que sempre devemos aplicar em nosso código enquanto que a composição naturalmente nos leva a usar tais conceitos.

Mas então eu nunca devo usar herança ??? (Nunca é uma palavra que nós mortais deveríamos pronunciar com muito cuidado....)

Não existe um mandamento para nunca usar herança, mas podemos definir algumas regras para identificar quando podemos usá-la de forma a não ter os problemas que ela acarreta:

Então , considere a utilização da herança se...:

- A classe Filha expressar "um tipo especial de" e não "ser um papel desempenhado por";
- Uma instância de uma classe Filha
NUNCA precisar tornar-se um objeto de outra classe;
- A classe filha estender ao invés de substituir total ou parcialmente as responsabilidades da classe Pai;
- A sua hierarquia de herança representar um relacionamento
"É um" e não um relacionamento "Tem um";
- Você desejar ou precisar realizar alterações globais para as suas classes filhas alterando uma classe Pai;
- Você precisar aplicar a mesma classe e métodos a diferente tipos de dados;
- Você puder comparar seu objeto A com outro B dizendo, que A  "É UM tipo de..." B.
- Você estiver construindo uma família de tipos (relacionados entre si)

Obs: Cuidado com a aplicação do princípio "È Um" às vezes ele nos leva a cometer erros que percebemos só depois de olharmos o código. (Vide a violação do princípio LSP ) - veja o artigo : O princípio de substituição de Liskok (LSP) Macoratti .net)

Agora concluindo : Herança e composição não são mutuamente exclusivas. Podemos usar as técnicas em conjunto para otimizar os resultados.

Lembre-se da regra máxima : "Programe para um a interface e não para uma implementação."

Na última aula do curso vamos apresentar o padrão IoC - Inversão de Controle.

Referências:


José Carlos Macoratti