Encapsular dados para Good Design e facilidade de manutenção em Swift

Considere o conceito de encapsulamento, um conceito importante da programação do objeto # 8208-oriented. A idéia por trás de encapsulamento é que os objetos devem ser opaco: Você não deve ser capaz de dizer o que está dentro de dados de um aplicativo, que funcionalidade que contém, ou o que as operações que realiza. Fazendo isso faz com que seus objetos flexível e reutilizável.

Este conceito provou o seu valor ao longo dos anos. O original # 173-arquitetura do Objetivo nº 8208-C consistiu de quadros de objetos (embora a palavra # 147-quadro # 148- não foi utilizado no início). Os objetos eram opacos para que os engenheiros de software não podia olhar dentro deles (ou, pelo menos, eles não deveriam). Um objeto chamado (digamos) myObject, foi assumida para ter alguns dados - talvez chamado dados - e estes dados em si estava fora # 8208 dos limites para os desenvolvedores.

Em vez de acessar os dados diretamente, os desenvolvedores aprenderam a enviar uma mensagem para myObject para obter seus dados. Por convenção, a mensagem seria nomeado objectData e causaria myObject para retornar os dados de myObject.

Se você olhar mais de perto este design, myObject é o de aula objectData é o nome da função ou método que serve como um getter. Outro método chamado (por padrão) setObjectData é o montador. O setter usa um único parâmetro (normalmente chamado (newObjectData).

Se fosse só o acesso objectData usando objectData para obtê-lo ou setObjectData para definir ou atualizá-lo. Uma consequência interessante e útil deste projeto é que objectData (os dados armazenados pela myObject) Não precisa existir.

Os acessores (objectData e setObjectData) Pode trabalhar com dados dinâmicos que nunca pode realmente ser armazenados. Com encapsulamento como este, você nunca precisa de saber se deve ou não os dados são armazenados ou calculados em tempo real. Tudo que você precisa saber é que myObject obtém dados para você com objectData e leva os dados de você com setObjectData.

Enquanto ambos os acessores de trabalhar, se ele é calculado em tempo real, armazenada em um banco de dados, ou até mesmo armazenado na lua não importa: myObject encapsula seus dados.

Outras línguas que lhe permitem acessar os dados diretamente usando uma sintaxe como myObject.objectData, mas porque a referência real aos dados, neste caso, seria myObject.objectData () - um método ou função de chamada (note os parênteses no final) - encapsulamento está completa.

A sintaxe hipotético mostrado nos parágrafos anteriores é uma versão genérica da sintaxe moderna ou # 147-dot sintaxe # 148- usado em Objective # 8208-C a partir do final dos anos 1990 em diante. Usando o estilo original do Objetivo nº 8208-C (às vezes chamado de formato de mensagem) A maneira para enviar a objectData a mensagem myObject seria com um código como este: [MyObject objectData].

Criando e preservando o encapsulamento tornou-se uma parte importante do desenvolvimento # Objectivo 8208-C. É verdade que o encapsulamento preserva muitas das características poderosas do Objetivo nº 8208-C e faz reutilização de código muito mais fácil, mas em alguns casos, o encapsulamento pode ser um pouco mais complicado de escrever e às vezes leva mais recursos para executar.

Assim, embora a estrutura não é particularmente complicado, armazenar, recuperar e definir o valor de uma variável exige três elementos.

Os componentes desta estrutura são:

  • uma variável ou código real para calcular-lo (isto é tudo invisível para você)

  • um método getter para obter o valor da variável (isto é visível para você)

  • um método setter para definir o valor da variável (isto é visível para você)

Em Objective # 8208-C 2 (lançado em 2007), propriedades nomeadas foram introduzidos. Eles fornecem uma maneira de simplificar essa estrutura, mas eles são totalmente compatíveis com ele. A propriedade chamada tem um formato como este:

@property (nonatomic forte,) ID detailItem- @ propriedade (fraco, nonatomic) IBOutletUILabel * detailDescriptionLabel-

A propriedade começa com a directiva de compilador @propriedade seguida pelos atributos de memória e uso de parênteses, como Forte, fraco, somente leitura, e nonatomic - os significados específicos não importa neste momento.

Seguindo os atributos entre parênteses são o tipo da propriedade e, em seguida, o seu nome. Para tipos de objetos, um ponteiro é usado. O tipo de classe identidade não é um ponteiro. Mais uma vez, os detalhes não importam neste momento.

O que importa é que, com uma declaração de propriedade, o compilador é capaz de declarar e criar uma automaticamente variável backing, que é a própria variável, onde os dados são armazenados. Também é capaz de criar um getter e um Setter utilizando as convenções descritas anteriormente (o getter é o nome da variável e o passador é setMyVariable).

Várias convenções entram em jogo aqui. Os nomes das variáveis ​​começar com uma letra minúscula. Se o nome da variável é composto por várias palavras, palavras após o primeiro começar com letras maiúsculas (isso é chamado camelCase). Métodos e funções começar com aulas de cartas- minúsculas começam com letras maiúsculas. As convenções encontrar-se em nome de um setter.

Considere uma variável chamada myVariable cuja setter é chamado setMyVariable. Isso está em conformidade com a convenção de que os métodos começam com letras minúsculas, e também está em conformidade com a convenção camelCase. No entanto, porque o encontro dessas duas convenções pode sugerir o nome setmyVariable, camelCase substitui outras convenções.

Assim, as propriedades nomeadas reduzir a quantidade de digitação necessária para usar propriedades por ter o compilador fazer o trabalho de criar os acessores get e set e de criar a variável de apoio.

Em alguns casos, os desenvolvedores têm necessário mais controle sobre as coisas. Os dois casos mais comuns deste foram os seguintes:

  • Quando um desenvolvedor precisa de uma variável de apoio para ter um certo nome e precisa ser capaz de acessá-lo diretamente.

  • Quando o setter ou getter precisa fazer mais do que apenas definir ou obter o valor de uma variável.

Aqui é onde a complexidade começa a entrar.

O sintetizador propriedade automatizado sintetiza uma variável de apoio com o nome da propriedade precedido por um sublinhado. Assim, o padrão backing variável para minha propriedade é _minha propriedade. (Você pode definir isso como uma opção na declaração de propriedade.)

Você também pode escrever seus próprios assessores. É comum ter-lhes executar tarefas adicionais acima e além de suas funções de assessor simples. Uma das mais comuns destas tarefas está a estabelecer uma ligação de dados de modo a que um absorvente pode obter um valor previamente armazenado para a sua propriedade.

Existem muitas outras variações sobre esta estrutura (incluindo propriedades que não têm variáveis ​​de apoio, mas simplesmente confiar em um getter para calcular ou recuperar um valor de base que # 8208-necessário). E, apenas para completar esta parte da imagem, você pode misturar e combinar propriedades, com variáveis ​​tradicionais (variáveis ​​nus não são parte de uma propriedade declarada).

Muitos dos argumentos contra o uso de propriedades nomeadas (e eles têm sido amargo) giram em torno do fato de que o acesso a um valor propriedades nomeado na variável de apoio requer mais recursos da máquina do que apenas acessar um local de memória. Com os computadores de hoje - mesmo em dispositivos móveis - isto pode parecer uma reação extrema, mas tem sido comum em alguns círculos.

Este, então, é o mundo das propriedades e variáveis ​​que aborda Swift. Se todas as suas complexidades e combinações são necessárias vale a pena discutir: Todos tem encontrado usos em aplicativos e até mesmo nos quadros da Apple que compõem Cocoa e Cocoa Touch.

Há uma outra camada de complexidade no que diz respeito às declarações de # 173 propriedades e variáveis. A maioria das declarações de classes de código # 8208-C Objective são colocados em um arquivo de cabeçalho no @interface seção. (Por convenção, este arquivo é nomeado com um .h após o nome da classe.)

Muito recentemente (no final dos anos 2000), tornou-se lugar comum para adicionar uma segunda @interface seção no formato de uma extensão de classe no corpo principal do arquivo de classe (o arquivo com o .m extensão). Declarações no arquivo de cabeçalho podem ser agrupados em seções com vários acessos - público, privado, e protegido. público e privado interfaces são apenas isso. protegido Os elementos da interface são visíveis a própria classe e para qualquer de suas subclasses.

Finalmente, dentro do arquivo principal (o .m arquivo de extensão), você pode acessar a variável de apoio usando seu nome, como em _myBackingVariable. Isto evita a utilização do absorvente e poupa alguns ciclos de máquina. Ele também pode lado # 8208-passo qualquer # 173 de processamento adicional de que o getter does- esta convenção pode ser muito útil.

Este é o fundo de propriedades e variáveis ​​em Objective # 8208-C e agora em Swift.

menu