Na palestra instigadora de Rich Hickey, Goto Conference " The Value of Values ", aos 29 minutos, ele está falando sobre a sobrecarga de uma linguagem como Java e faz uma declaração como "Todas essas interfaces matam sua reutilização". O que ele quer dizer? Isso é verdade?
Na minha busca por respostas, encontrei:
O PRINCÍPIO DO MENOR CONHECIMENTO AKA A Lei de Demeter, que incentiva interfaces de API herméticas. A Wikipedia também lista algumas desvantagens.
A crise de roupas imperiais de Kevlin Henney, que argumenta que usar, não reutilizar, é o objetivo apropriado.
" Stop Writing Classes ", de Jack Diederich, que argumenta contra o excesso de engenharia em geral.
Claramente, qualquer coisa escrita mal o suficiente será inútil. Mas como a interface de uma API bem escrita impediria que esse código fosse usado? Ao longo da história, existem exemplos de algo feito para uma finalidade sendo usado mais para outra coisa . Mas no mundo do software, se você usa algo para um propósito a que não se destina, geralmente ele quebra.
Estou procurando um bom exemplo de uma boa interface que impede o uso legítimo, mas não intencional, de algum código. Isso existe? Não consigo imaginar.
fonte
Respostas:
Não assisti a apresentação completa de Rich Hickey, mas se eu o entendi corretamente, e a julgar pelo que ele diz sobre a marca de 29 minutos, ele parece estar discutindo sobre os tipos que matam a reutilização. Ele está usando o termo "interface" como um sinônimo de "tipo nomeado", o que faz sentido.
Se você possui duas entidades
{ "name":"John" }
do tipoPerson
e{ "name": "Rover" }
do tipoDog
no Java-land, elas provavelmente não poderão interoperar, a menos que compartilhem uma interface ou ancestral comum (comoMammal
, o que significa escrever mais código). Assim, as interfaces / tipos aqui são "matar sua reutilização": emboraPerson
eDog
têm a mesma aparência, não pode ser usado de forma intercambiável com o outro, a menos que você escrever código adicional para suportar isso. Nota Hickey também brinca sobre projetos em Java que precisam de muitas classes ("Quem aqui escreveu um aplicativo Java usando apenas 20 classes?"), O que parece uma consequência do exposto acima.Em linguagens "orientadas a valores", no entanto, você não atribui tipos a essas estruturas; são apenas valores que compartilham a mesma estrutura (no meu exemplo, ambos têm um
name
campo com um valor String) e, portanto, podem interoperar facilmente, por exemplo, podem ser adicionados à mesma coleção, passados para os mesmos métodos, etc.Em resumo, tudo isso parece ter algo a ver com igualdade estrutural versus tipo explícito / igualdade de interface . A menos que eu tenha perdido algo das partes do vídeo que ainda não assisti :)
fonte
ERROR: Object doesn't have a property called "name"
geralmente é o resultado devalue-oriented
idiomas e o outro problema é quando você não deseja mais chamar essa propriedadename
. Boa sorte na refatoração, porque provavelmente há centenas de objetos com uma propriedade,name
mas nem todos sãoPerson
ouDog
.interface
s, mas à bagunça que é o projeto Java típico.Ele provavelmente está se referindo ao fato básico de que uma interface não pode ser instanciada. Você não pode
reuse
uma interface. Você só pode implementar código que o suporte e, quando você escreve código para uma interface, não há reutilização.O Java tem um histórico de fornecer estruturas de muitas APIs que usam uma interface como argumentos, mas a equipe que desenvolveu a API nunca implementa uma ampla variedade de classes para você reutilizar com essas interfaces.
É como uma estrutura de GUI que possui uma
IWindow
interface para uma caixa de diálogo e, em seguida, você pode adicionarIButton
interfaces para controles. Exceto, eles nunca lhe deram uma boaButton
aula que implementaIButton
. Então você fica criando o seu próprio.Estruturas abstratas que possuem uma ampla variedade de classes base, fornecendo funcionalidades principais, são mais reutilizáveis e funcionam melhor quando essas classes abstratas são acessíveis àqueles que usam a estrutura.
Os desenvolvedores de Java começaram a fazer isso onde suas camadas de API eram expostas apenas
interfaces
. Você poderia implementar essas interfaces, mas nunca poderia reutilizar classes do desenvolvedor que implementou essas interfaces. É como um estilo de capa e punhal de desenvolvimento de API.fonte
Acho que o slide 13 de sua apresentação ( O Valor dos Valores ) ajuda a entender isso:
Meu entendimento é que Hickey sugere que, se eu precisar, digamos, dobrar o valor que você enviou para mim, eu simplesmente escrevo um código parecido com
Veja, o código acima é o mesmo, independentemente do valor que você enviou - uma reutilização perfeita .
Agora, como isso seria na linguagem com objetos e interfaces?
Oh espere! e se
YourValue
não implementarDoublable
? não que não possa ser duplicado, pode perfeitamente ser, mas ... e se simplesmente não houver métodoDouble
? (e se houver um método chamado digamosTwiceAsMuch
?)Oh, nós temos um problema.
YourValue.Double
não funcionará, não poderá mais ser reutilizado . Pela minha leitura do slide acima, é sobre o que Hickey quis dizer quando disse: "Todas essas interfaces matam sua reutilização!"Veja bem, as interfaces assumem que os objetos são passados "junto com seus métodos", juntamente com o código que opera neles. Para usar objetos, é preciso entender como chamar esse código, qual método chamar.
Quando o método esperado está ausente, há um problema, mesmo que semanticamente , a operação desejada faça todo o sentido para um objeto. Conforme declarado na apresentação, os valores não precisam de métodos ("Posso enviar valores sem código e você está bem"), permitindo escrever código lidando com eles de maneira genérica.
Nota lateral: a noção de passar valores sem código de alguma forma me lembra um padrão Flyweight no OOP.
Os usos do flyweight que eu vi normalmente seguiram a mesma abordagem de remover o código (métodos, interfaces) dos objetos e distribuir coisas ao redor, bem como valores sem código , esperando que o código de recebimento tenha os meios necessários para operar com eles.
Isso parece muito com o slide "valores não precisam de métodos. Posso enviar valores sem código e você está bem".
fonte
MyValue = Double(YourValue)
não faz sentido se YourValue for uma String, um Endereço, um Usuário, uma Função ou um Banco de Dados. Caso contrário, seu argumento do método ausente é forte. OTOH, os métodos de acesso permitem impor várias restrições para que seus Valores sejam válidos e que apenas operações sensíveis sejam usadas para produzir novos Valores. Se, posteriormente, você decidir separar o endereço do usuário e da empresa, os métodos de acesso significam que você não quebra todos os clientes do seu código. Portanto, eles podem ajudar a reutilizar a longo prazo, mesmo que às vezes o impeçam no curto prazo.Em um (ie) meu, classes e interfaces ideais do mundo sempre descreveriam o comportamento, mas o fato é que, com muita freqüência, eles acabam descrevendo dados. Ontem, vi o vídeo de alguém criar uma
BankAccount
classe chamada que nada mais era do que um glorificadoint
(na verdade, era muito menos útil do que umint
, portanto, 'matando' a reutilização que eu teria, se simplesmente fosse deixada como umaint
), tudo em nome de "bom" design. A quantidade de código, suor e lágrimas desperdiçados na reinvenção contínua de representações complicadas de dados é impressionante; se você não estiver usando os dados de maneira significativa, deixe estar.Agora, este é o estágio em que Rich Hickey se contenta em jogar o bebê fora com a água do banho e dizer que todos devemos viver na terra dos valores (um vizinho do reino dos substantivos). Penso, por um lado, que o POO pode e promove a reutilização (e, principalmente, a descoberta, que acho que falta na programação funcional) quando empregado criteriosamente. Se você está procurando um princípio de POO que capte melhor essa tensão, acho que pode ser http://c2.com/cgi/wiki?TellDontAsk (que, obviamente, é um primo próximo de Demeter)
fonte