Exemplos Java e C / Linux Tweet

Esconder e Encapsulamento em C ++

Todos nós já ouvimos sobre o encapsulamento de informações nos idiomas Orientado para objetos e em C ++. Vamos ver aqui o que consiste e alguns “truques” que podemos fazer no caso específico de C ++ e que geralmente não vêm nos livros desta linguagem (embora em livros sobre padrões de design).

Os pontos que veremos são:

    • Ataque dos trampoleiros em uma classe
    • importância da lenegnalesulacional para compilar em C ++
    • encapsulamento através de interfaces

    encapsulamento dos atributos de uma classe

    antes de tudo, deve ser claro que o encapsulamento, assim como qualquer bom Hábito de programação (como não colocar, comentário, etc.) é útil para o código que pode mais tarde ser reutilizado ou modificado, por outras pessoas ou por si mesmo. Se eu fizer um programa marciano e nunca pretendo tocá-lo novamente, não importa o quanto eu faço com gotes e sem comentar enquanto eu me encontro enquanto estou fazendo isso e funciona. Eu pagarei este “pecado” se dentro de dois meses eu posso pensar em melhorá-lo ou quero reutilizar algo de seu código para outro programa.

    Eu comente isso porque o encapsulamento, levou ao fim, como é o caso do ponto final das interfaces, torna a programação um pouco mais complicada (você tem que fazer mais classes). Este esforço é apenas recompensado se o código for muito grande (evitando recompila desnecessário) ou será reutilizado no futuro (podemos extrair classes com menos dependências de outras classes). Dito isto, vamos para o assunto.

    Qualquer curso de orientação de objetos nos diz que é melhor colocar os atributos de uma classe protegida ou privada (nunca pública) e acessá-las através de métodos públicos que colocamos na aula. Vamos ver o motivo. Suponha, por exemplo, que você peça um programa que permita trazer uma lista de pessoas com suas datas de nascimento. Entre outras coisas, decidimos nos tornar nossa aula de data com vários métodos maravilhosos da seguinte maneira.

    Data de classe: Public:
    int anho; // o anho com quatro figuras, por exemplo. 2004
    int Mês; // O mês, de 1 a 12
    Day; // o dia, de 1 a 31
    MethodeMaravilloso1 void ();
    void methodomaravillos2 ();
    };

    já fizemos a aula. Agora, fazemos o resto do código e em algumas milhares de linhas de código, usamos coisas assim diretamente.

    data Unacy;
    UNACCHA.ANHO = 2004;
    Unaccha.mes = 1;
    UNACCHA.DIA = 25;

    Finalmente terminamos nosso programa e tudo funciona muito bem. Alguns dias depois, eles nos dizem que o programa vai manter tropérios mil pessoas e que recebem muitos arquivos, do que ver se podemos fazer algo para remediar. Uau, armazenamos uma data com três inteiros. Se usarmos o formato da maioria dos computadores, em que a data é o número de segundos desde 1º de janeiro de 1970 (que nos retorna a função de tempo ()), é suficiente com um inteiro.

    Total, quais as mãos são alteradas, mudam nossa classe para que ela tenha o seguinte:

    data de classe:

    / * comentou por porinefetic
    Intanho; Intmes;
    Intdia; * /

    longnumerseconds;

    voidmetodomaraviloso1 ();
    void methodomaravillos2 ();
    };

    já é feito o fácil. Agora você só tem que passar pelas tropédias mil linhas de código, alterando nossas tarefas e leituras para os três inteiros anteriores pelo novo longo.

    Teria sido muito melhor se tivéssemos feito esses três inteiros e métodos protegidos para acessá-los. Algo como este

    CLASS DATA:

    Void Tomafecha (Int Anho, Int Mês, Intdia);
    Int Damaano ();
    intames ();
    intamédia ();
    MethodeMaravilloso1 void ();
    void methodomaravillos2 ();
    Protegido:
    int Anho; // o anho com quatro figuras, por exemplo. 2004
    int Mês; // O mês, de 1 a 12
    Day; // O dia, de 1 a 31
    };

    Se agora tivermos que fazer a mesma mudança, basta alterar os atributos protegidos. Os métodos Tomaxxx () e Damexxx () são mantidos em termos de parâmetros e valor retornado, mas seu código interno é modificado para fazer o ano, mês e dia em um longo segundo e de cabeça para baixo. O resto do código não precisa tocá-lo.

    É ainda melhor fazer os atributos privados que protegem. Tornando-os protegidos, as classes das filhas (aqueles que herdam da data) podem acessar diretamente esses atributos. Quando fizemos a mudança por um longo, também devemos alterar o código das classes da filhas. Se os atributos forem privados e forçamos as classes das filhas a acessá-las por meio de métodos, não teremos que alterar o código dessas classes de filhas.

    Acesso através de métodos é menos eficiente do que fazê-lo diretamente, portanto, após o princípio da ocultação, é melhor tornar os atributos privados, por eficiência em alguns casos, talvez seja melhor torná-los protegidos (ou mesmo público ) Risco de ter que alterar mais linhas de código em caso de mudança.

    aconselhamento: sempre que possível os atributos de uma classe privada.

    importância do encapsulamento em C ++

    com o que é contado até agora, evitamos Tem que alterar o código no caso de alteração de parâmetros.

    Na caixa concreta de C ++, há um pequeno problema adicional. É normal tornar as classes definidas por meio de dois arquivos. No caso da aula de data, teríamos uma data.h com a definição da classe e uma data.cc (ou .cpp) com o código dos métodos de classe. Quando queremos usar a aula de data, geralmente fazemos nossa #include < data.h >.

    Qualquer processo de compilação eficiente (como o Linux torna o utilitário e acho que o Visual C ++) está pronto o suficiente para recompilar apenas os arquivos que precisam ser recompilados. Isto é, se já tivermos nosso projeto compilado e jogamos um arquivo, o compilador só compilará esse arquivo e todos aqueles que dependem dele. Esses recursos são muito importantes em grandes projetos (com muitos arquivos e muitas linhas de código), para salvar o tempo de compilação cada vez que fizermos uma modificação (eu trabalhei em projetos que levou para compilar do zero em torno de 4 horas).

    Qual é o problema? O problema é que, se decidirmos, por exemplo, alterar novamente o atributo privado da classe de data para outra coisa, precisamos tocar na data do arquivo. Isso fará com que todos os arquivos que #incluem < Data. Isso, por sua vez, isso acontece. Bem, assim por diante.

    A solução é evidente, local tão pouco quanto possível na data. h, especificamente as variáveis #definas e globais que não são necessárias para ver de outras classes.

    Por exemplo, a nossa aula de data pode ter algum #define para indicar qual é o número mínimo e máximo de mês. É melhor colocar esses #define na data. CC em vez de data. H, a menos que alguém tenha que vê-los.

    // este melhor no .cc do que no .h
    #define mes_minimo 1
    #define mes_maximo 12
    conselho:
    sempre que possível, colocando O # define, tipos de definição, constantes globais, etc, dentro da Delfichero.cc

    Encapsulation através de interfaces

    temos uma coisa restante. Por que temos que recompilar muitas coisas se mudarmos um atributo privado da turma? O ideal seria para ser capaz de mudar as coisas internas da classe sem ter que recompilar qualquer outra coisa, afinal, o atributo é privado e ninguém o usa diretamente.

    É bastante comum em programação orientada a objetos O uso de interfaces para fazer as classes dependerem umas das outras. No caso de C ++, o uso de interfaces também é útil para evitar recompilares desnecessários.

    Uma interface não é mais do que uma classe em que os métodos públicos necessários são definidos, mas eles não são implementados. Em seguida, a classe concreta que queremos herdar dessa interface e implementa seus métodos.

    No nosso caso, podemos fazer uma classe de interface, com métodos públicos virtuais puro (nenhum código). Em seguida, a classe de data herda da interface e implementa esses métodos.

    no arquivo de interface. Virtual Int Damaano () = 0;
    Virtual int Damemes () = 0;
    Virtual int Damédia () = 0; METODOMARAVILLOSO VERTUAL VOIDOMARAVILLOSO1 () = 0; Virtual Void Methodomaravillos2 () = 0;
    };

No momento, nem existiria uma interface. CC

A classe de data ainda é a mesma, mas herdada da interface.

#include < intercefea.h >

classe da classe: Interface pública> Público:
Void Tomafa (Int Anho, Int Mês, Intdia);
Int Damaano ();
intames ();
intamédia ();
MethodeMaravilloso1 void ();
void methodomaravillos2 ();
Protegido:
int Anho; // o anho com quatro figuras, por exemplo. 2004
int Mês; // O mês, de 1 a 12
Day; // O dia, de 1 a 31
};

Agora, todos que precisam de uma data, tem que ter um ponteiro para interface em vez de data. Alguém irá instalar a data e mantê-lo nesse ponteiro. Isto é, nós poderíamos fazer algo assim

#include < data.h >
#include < interface. >
…Interface infectada * Unacy = null;

Unacho = Nova Data ();
Unaccha- > Tomacca (2004, 1, 27);

excluir Uny;
Unaccha = null;

Se parecemos um pouco, ainda não consertamos nada, a menos que complicasse o assunto. Aquele que este código precisa fazer agora #include tanto o interfacefea.h e date.h. Se tocarmos algo na data. H, este código será recompugiado.

Este código precisa #include < date.h > para poder fazer a data da data. Você tem que procurar como evitar isso novo. Geralmente, é também bastante comum fazer uma aula (ou usar a mesma interface se o idioma permitir, como é o caso de C ++) para colocar um método estático que o novo e devolvê-lo para nós.

No caso de Java, colocando este método, não teríamos mais uma interface, mas uma classe. Fazendo informam a data herdada nos limites para não herdar de qualquer outra coisa (Java não suporta herança múltipla). Se isso é admissível, podemos fazer assim. Se precisarmos dessa data herdada de outra classe, em vez de colocar o método estático na interface, devemos fazer um terceiro gerador separadamente com este método estático.

No nosso exemplo C ++, a classe de interface seria deixada.

classe interfaceface
{
Public:

staticinterfacefacea * damenuevafecha ();

Virtual Voidtomacy (Intanho, intmes, int dia) = 0; Virtual Int Damaano () = 0;
Virtual int Damemes () = 0;
Virtual int Damédia () = 0; METODOMARAVILLOSO VERTUAL VOIDOMARAVILLOSO1 () = 0; Virtual Void Methodomaravillos2 () = 0;
};

Agora precisamos de uma interface. CC. Dentro dele teremos

#include < interface .h >
#include < data.h >

interface * interface infectada :: Damenuevafecha ()
{
Retorna nova data ();
}

O código que anteriormente usou o ponteiro para a interface seria agora

#include < Interface. >
interface * unaccha = null;

Unaccha = Interface infectada :: Damenuecha ();
Unaccha- > Tomacca (2004, 1, 27);

excluir Uny;
UNACCHA = NULL;

Como vemos, apenas o #include do interfacefeafe.h e isso não inclui data.h (faz a interface. CC, não o .h). Nós fizemos este código não ver em tudo no prazo. Agora podemos jogar sem uma olhada na data. H, que esse código não precisa ser recompilado.

Uma vantagem adicional é que você pode alterar a data de data para outra data de classe2 no tempo de execução. Seria suficiente para colocar um atributo estático na interface para indicar qual data de aula queremos e fazer o método Damenuevacha () Instantie e retorna um ou outro, dependendo desse atributo.

Dica:
Use interfaces paraquelas clasque chorão que você pode alterar o pedido de Developtope de Developtoo de Developtoo.

Este mecanismo obtém uma instância de uma única classe através de um método estático e Uma interface, de modo a não depender da classe específica, acho que dentro do mundo dos padrões de design é o padrão de fábrica.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *