Aqui estão alguns argumentos para propriedades e meus contra-argumentos:
Mais fácil de usar do que escrever métodos getter e setter
Os pares de métodos getter e setter são cheiros de código. Tornar mais fácil escrever isso é como tornar mais fácil a reprovação em um teste de matemática usando um formulário Scantron e preenchendo todos os 'C'. Objetos que contêm apenas estado, por persistência, não devem usar getters / setters e devem criar objetos imutáveis no momento da persistência.
O que é importante para um consumidor de um objeto é o que ele faz, não como ele faz. Seu comportamento é o que faz; seu estado é como ele faz isso. Se você se preocupa com o estado de um objeto (exceto pela persistência, embora isso também interrompa o OO), você simplesmente não está fazendo POO e perdendo suas vantagens.
Eles fornecem uma indicação aproximada do desempenho para os consumidores
Isso é algo que pode mudar no futuro, para qualquer propriedade. Suponha que na versão 1.0, acessar o PropertyX simplesmente retorne um campo. Na liberação 1.5, se o campo for nulo, o PropertyX usa o padrão Objeto Nulo para criar um novo objeto nulo. Na versão 2.0, o campo está sendo validado ainda mais pelo método getter no PropertyX.
À medida que a propriedade se torna cada vez mais complexa, a indicação de desempenho do uso de uma propriedade parece cada vez menos verdadeira.
Eles são melhores que os campos públicos
Isso é verdade. Mas o mesmo acontece com os métodos.
Eles representam um aspecto fundamentalmente diferente de um objeto que um método, e todos os consumidores do objeto devem se preocupar com isso.
Tem certeza de que ambas as afirmações acima são verdadeiras?
Eles são mais fáceis de digitar, cara
Claro, digitar myObject.Length
é mais fácil do que digitar myObject.Length()
, mas isso não poderia ser corrigido com um pouco de açúcar sintático?
Por que usar métodos em vez de propriedades?
Sem garantias de desempenho. A API permanecerá verdadeira, mesmo que o método fique mais complexo. O consumidor precisará criar um perfil de seu código se estiver enfrentando problemas de desempenho e não confiar na palavra da API.
Menos para o consumidor pensar. Esta propriedade possui um setter? Um método certamente não.
O consumidor está pensando a partir de uma mentalidade OOP adequada. Como consumidor de uma API, estou interessado em interagir com o comportamento de um objeto. Quando vejo propriedades na API, ela se parece muito com o estado. De fato, se as propriedades fizerem muito, elas nem deveriam ser propriedades; na verdade, as propriedades em uma API SÃO como elas aparecem para os consumidores.
O programador da API pensará mais profundamente sobre métodos com valores de retorno e evitará modificar o estado do objeto nesses métodos, se possível. A separação de comandos das consultas deve ser aplicada sempre que possível.
Então, pergunto: por que usar propriedades em vez de métodos? A maioria dos pontos no MSDN são odores de código por si só e não pertencem a propriedades ou métodos.
(Esses pensamentos vieram a mim depois de pensar no CQS.)
type GetFoo() void SetFoo()
dez mil vezes. Durante todo o meu tempo escrevendo código C #, nunca fui confundido com uma propriedade.Respostas:
Por que são "métodos contra propriedades"? Um método faz alguma coisa. Uma propriedade é, bem, um membro de um objeto. São coisas totalmente diferentes, embora dois tipos de métodos comumente escritos - getters e setters - correspondam às propriedades. Como comparar propriedades com métodos em geral não é significativo, presumo que você quis falar sobre getters / setters.
Não necessariamente, eu diria, mas de qualquer forma isso não é uma questão de getters / setters vs. propriedades, mas uma questão de se alguma delas deve ser usada. Observe também que, por exemplo, você pode deixar de fora a
setX
peça, assim como criar propriedades somente leitura.Uma atitude altamente questionável. Se a GUI quiser gerar dados mantidos por a
DataStuffManagerImpl
, precisará obter esse número de alguma forma (e não, colocar metade do aplicativo na classe de widget não é uma opção).Em quase todos os casos, toda a lógica de validação, etc. ainda é efetivamente O (1), ou de outro modo, com custo negativo. Caso contrário, talvez você tenha ido longe demais e esteja na hora de mudar. E um
getX()
método também é geralmente tratado tão barato!As propriedades são esse açúcar sintático.
"Existe um levantador para este caçador?" Mesma diferença.
Não sei o que você está tentando nos dizer aqui. Para propriedades, existe uma lei não escrita ainda mais forte para não causar efeitos colaterais.
fonte
obj.x = y
mapeiaobj.setX(y)
eobj.x
mapeia paraobj.getX()
. Como isso é diferente?Essa é uma suposição defeituosa e completamente incorreta. Os métodos Get / Set são uma maneira de encapsular um membro de dados e não são de forma alguma um "cheiro de código". Eu realmente odeio a maneira como algumas pessoas usam o termo "cheiro de código", mas de qualquer maneira ...
Parece uma API mal projetada, não vejo como isso é culpa da sintaxe da propriedade.
As propriedades em C # eram simplesmente açúcar sintático para um padrão muito comum que tornava nossas vidas como programadores um pouco mais fáceis. No entanto, hoje em dia, se você deseja usar a ligação de dados, "deve" usar propriedades, portanto, agora elas são um pouco mais que o açúcar sintático. Acho que realmente não concordo com nenhum dos seus pontos e não entendo por que você não gosta de um recurso de linguagem que suporte diretamente um padrão comum.
fonte
Sua premissa está errada.
As propriedades não são de forma alguma um contrato para desempenho, implementação interna ou qualquer outra coisa.
Propriedades são pares de métodos especiais, que representam semanticamente um atributo, se você desejar. E, portanto, o único contrato é que uma propriedade se comporte como você esperaria que um atributo se comportasse.
Se eu pedir a cor de um objeto, não suponho se é obtido por um acesso simples a um campo ou se é calculado a tempo.
O ponto principal é ter a capacidade de expor o comportamento de um atributo usando métodos, enquanto é transparente para o consumidor da interface, esteja você usando um campo ou acessadores.
Ter atributos (e realmente ocultar sua implementação, como propriedades opostas a campos) é um recurso declarativo poderoso , que é a base para ter inspetores de objetos visuais e outra geração automática de visualizações, para ligação de dados e muitas outras coisas úteis. E o mais importante, ele também transporta claramente essas informações para seus colegas programadores.
fonte
Uma propriedade deve ser um estado. Se o código subjacente do setter ou getter for alterado para adicionar significativamente ao processamento necessário para definir ou obter o estado, na verdade não será mais uma propriedade e você deverá substituí-lo por métodos. Isso depende de você como desenvolvedor do código.
Colocar código demais (quanto depende demais) em um setter ou getter está errado, mas apenas porque é possível não é uma razão para descartar o padrão em todos os casos.
fonte
Uma coisa que está faltando e eu não sei se isso é devido à ignorância ou se você está intencionalmente ignorando esse detalhe, é que as propriedades SÃO métodos.
Quando você usa a sintaxe de propriedade do C #, o compilador silenciosamente cria métodos getter e setter com metadados que informam aos idiomas que entendem as propriedades como um recurso sintático de primeira classe para tratá-las como tal. Na verdade, esse é o açúcar sintático que você está pedindo. Algumas linguagens que podem ser executadas no CLR não escondem completamente esses detalhes de você (Boo, se a memória me servir e algumas implementações do Lisp), e você pode chamar explicitamente os getters e setters.
As propriedades ocasionalmente têm efeitos colaterais, como acionar eventos de notificação de alterações (INotifyPropertyChanged, por exemplo) ou marcar uma instância de uma classe como suja. É aqui que eles têm seu valor real, apesar de criá-los é um pouco mais trabalhoso (exceto no Boo, que possui macros que aceitam sintaxe).
Agora, a questão mais ampla é se os métodos getter e setter são, de fato, uma coisa boa. Existem claramente trocas; se você tiver métodos mutadores, seu código é inerentemente menos paralelizável, porque agora você precisa lidar com problemas de sincronização de threads. E é bem possível que você corra o risco de violar a Lei de Demeter usando métodos mutadores (sejam chamados de propriedades ou métodos getter / setter; são equivalentes), porque é muito conveniente fazê-lo.
Mas às vezes é a coisa certa a fazer. Às vezes, seu problema é pegar dados de alguma fonte, alterá-los um pouco, apresentar os dados atualizados ao usuário e salvar as alterações. Esse idioma é bem servido pelas propriedades. Como o artigo de Allen Holub diz, apenas porque getters e setters têm problemas não significa que você nunca deve usá-los. (Papagaio abstrato Guruspeak considerado prejudicial). Mesmo quando você segue a abordagem Classe / Responsabilidades / Colaboradores, ainda acaba expondo informações ou apresentações de informações a alguém; o objetivo é minimizar a área da superfície do emaranhado.
A vantagem das propriedades é que é muito fácil ter outro objeto tirando vantagem delas. A desvantagem das propriedades é que é muito fácil ter outro objeto tirando vantagem delas, e você não pode impedir isso facilmente.
A mutação de objeto faz sentido na camada do controlador, em, por exemplo, uma arquitetura MVC. Esse é o seu colaborador. Sua visão também é um colaborador, mas não deve estar mudando diretamente seus objetos, porque possui responsabilidades diferentes. A inserção de código de apresentação nos objetos de negócios também não é necessariamente a maneira correta de evitar getters / setters.
A equação muda um pouco se você usar abstrações funcionais, em vez de puras OO, que geralmente tornam as cópias de um objeto "registro" com algumas alterações bastante triviais, embora não gratuitas. E ei, se você está tentando obter garantias de desempenho, as propriedades geralmente são mais previsíveis do que a reconstrução lenta de uma coleção imutável.
fonte
Outro motivo importante em meu livro para usar propriedades é que elas podem aumentar bastante a legibilidade.
é claramente muito menos legível do que
fonte
Você tem quase o ponto de vista religioso oposto a mim :)
Quando mudei de Delphi para Java, a falta de propriedades foi uma grande afronta para mim. Eu estava acostumado a declarar uma propriedade e apontá-la diretamente para uma variável privada ou escrever um getter & setter (protegido) e depois "encaná-los" na propriedade. Isso encapsulou a propriedade e controlou como ela deveria ser acessada de uma maneira clara e inequívoca. Você pode ter uma propriedade somente leitura que calcule o total quando acessado e a chame de "Total" e não "_getTotal ()" ou ballochs semelhantes. Isso também significava que você poderia restringir o acesso às propriedades, protegendo-as na classe base abstrata e movendo-as para público ou publicadas em subclasses.
Para mim, as propriedades são uma maneira mais natural e expressiva de definir e obter o estado do objeto. Confiar em convenções de codificação não forçadas é mais um "cheiro de código" do que qualquer coisa para a qual você esteja criticando as propriedades. Além disso, como outros disseram, apresentar um uso mal projetado de propriedades e usar suas falhas para tentar descartar o conceito de propriedades em geral é uma forma extremamente ruim. É possível que você tenha visto apenas o mau uso das propriedades e suponha que seja assim, suponho, mas você deve fazer mais pesquisas antes de se tornar dogmático demais.
fonte
sorted
propriedade paratrue
. Portanto, configurá-lo parafalse
fornece a lista original. : D Ou embaralha aleatoriamente? : D Ou o que for, é apenas estúpido. Além disso, é muito lento em comparação com um conjunto classificado adequado. As propriedades não são ruins, mas aprendi a usá-las com moderação (até o ponto de ficar bastante feliz com getter e setters; estou usando principalmente Java).Uma das razões pelas quais as propriedades foram introduzidas no Java Beans Framework foi permitir a integração com um IDE - você pode arrastar esses componentes para o IDE e editar as propriedades usando editores de propriedades.
(naquela época, eles eram apenas receptores e levantadores regulares - e eram definidos apenas pela convenção de nomenclatura - e isso realmente cheirava)
Atualmente, existem ainda mais casos em que as propriedades são acessadas e modificadas, não através de código regular - como durante a depuração.
fonte
Um outro ângulo - eles realmente vieram do VB. Lembre-se, nos dias sombrios do século XX, quando o .NET foi concebido, uma das principais ênfases foi a substituição fácil e fácil do VB, para que seus programadores de VB pudessem arrastar e soltar as coisas nos formulários da web. O VB tinha propriedades, então você precisava manter esse recurso para que as coisas fossem traduzidas corretamente.
fonte
Há pelo menos dois propósitos para propriedades:
Eles são conceitualmente idênticos aos campos, mesmo que sejam implementados de maneira diferente. Um getter não deve alterar o estado do objeto e não deve ter efeitos colaterais. Um levantador só deve alterar o estado de maneiras conceitualmente semelhantes à modificação de um campo e não ter outros efeitos colaterais.
Eles são sintaticamente idênticos aos campos públicos (possivelmente somente leitura). Isso significa que um campo público pode ser alterado para uma propriedade sem interromper os chamadores no nível de origem.
fonte