Encapsulamento

Encapsulamento é uma das bases da Orientação a Objetos onde a idéia principal é tornar cada objeto auto-suficiente (na medida do possível). Com isso podemos gerar código com um grande índice de reuso, além de facilitar a manutenção.

Vamos tomar como exemplo um ComboBox:

Você adiciona o componente no Stage e insere os dados no mesmo (label, data, etc), certo? O componente é responsável por exibí-los. Assim, podemos dizer que você usa um ComboBox e tem acesso às propriedades necessárias para personalizá-lo ao seu modo (Talvez o combo do flash não seja o melhor exemplo de personalização, mas essa é outra história). Já pensou se você precisasse programar um código para que depois de um numero x de elementos fosse inserida uma rolagem no combo? Felizmente, neste conceito (e no do Flash, graças a Deus!), você não precisa. O combo é responsável pelos seus estados (lembre dessa palavra! Vamos lá, repita comigo: estado, estado, estado…), e é ele quem deve cuidar da sua rolagem independente do número de itens que possua.

Vamos supor que o nosso combo possua uma variável estática (que consequentemente tem o mesmo valor para todos os combos – ou em se tratando de OOP propriamente dita, para todas as instâncias do objeto) chamada MIN_ELEMENTS, que é responsável por armazenar o número mínimo de elementos visíveis, cuja declaração seria a seguinte:

public static var MIM_ELEMENTS:Number = 1;

Então, por descuido ou qualquer outro motivo alguém resolve escrever o código:

ComboBox.MIM_ELEMENTS = -10;

A variável é publica e pode ser acessada de qualquer lugar. Mas me diga, é possível renderizar -10 itens? Você acha possível que a alteração de um atributo como este poderia afetar o funcionamento do combo? É provável que sim. Não precisamos ter acesso a atributos deste gênero para utilizar o nosso objeto combo, mas é um dado importante dentro do mesmo. Assim a declaração correta seria:

private static var MIM_ELEMENTS:Number = 1;

Agora esse atributo só é visível dentro da classe e só pode ser alterado internamente.

Vamos a outro exemplo. Temos uma classe Pessoa e um de seus atributos é sexo e seu conteúdo pode ser feminino ou masculino.

class Pessoa
{
    public var sexo:String;
    // continua o codigo
    //  ...
}
 
var p:Pessoa = new Pessoa();
p.sexo = "Maria";

A variável sexo é pública e do tipo String portanto poderia aceitar tranquilamente a String“Maria”, entretanto, isso pode – e provavelmente irá – comprometer o funcionamento do nosso objeto, tendo em vista que o sexo “Maria” definitivamente não existe. Assim, utilizamos recursos de encapsulamento de OOP para proteger o nosso objeto. Os getters e os setters.

class Pessoa
{
    private var _sexo: String;
 
    public function get sexo():String
    {
        return _sexo;
    }
 
    public function ser sexo(value:String)
    {
        value = value.toLowerCase();
        if (value == "feminino" or value="masculino")
            _sexo = value;
 
        // caso nao fosse atribuido poderia ser disparado um evento,
        // ser gerada uma excessao,
        // exibir uma mensagem de erro e por ai vai.
    }
}

No exemplo acima, garantimos que será inserido apenas um dado válido. E o getter? Bom, se você restringe o acesso a um dado e ele precise ser visto fora do objeto, é necessário disponibilizá-lo (se e somente se ele realmente precisa ser visto de fora). Mas não confunda! O getter pode conter outras coisas além do retorno do atributo.

Geralmente quando se começa a aprender OOP (seja para criar o hábito, começar a identificar necessidades, ou qualquer outra coisa que se possa querer com isso) se indica utilizar atributos privados para tudo (ou quase) e a criação de getters/setters de todos eles. Isso porque quando se vem de uma linguagem procedural se pode fazer tudo com todos os “atributos”, não existe encapsulamento e literalmente “todo mundo é de todo mundo”. Então tenta-se a criar (ou modificar) uma cultura. Se isso é certo ou não… é um jeito (e a maioria dos programadores em algum momento passam por essa fase, depois passamos a fase de nos livrar do hábito do excesso).

A identificação das necessidade da utilização desses metodozinhos vem com a experiência. É preciso saber identificar quando o usuário pode inserir um dado diretamente, quando ele pode ver um dado, quando ele pode inserir algum dado mas com restrições, quando você precisa saber se um dado é inserido, etc… Uma forma de saber isso antes de colocar a mão na massa é a modelagem. O código abaixo por exemplo é apenas uma maneira burocrática de “gerar uma variável pública”.

private var _sexo: String;
 
public function get sexo():String
{
    return _sexo;
}
 
public function set sexo(sexo:String)
{
    _sexo = sexo;
}

Então… Vamos modelar, modelar e modelar?

Leave a comment