Recentemente, eu estava considerando que, às vezes, vários objetos dependem um do outro (por exemplo, se eles contêm referências cíclicas) e, portanto, seria útil criá-los como parte de uma operação atômica que garante que, após a construção, os novos objetos cumpram alguma restrição coletiva. .
Para fazer isso, é possível ter construtores que podem criar mais de um objeto. O programador colocaria em um único construtor todo o código, garantindo que, uma vez criados os objetos o 1 , ..., n , eles satisfizessem todas as restrições necessárias (por exemplo, todos os links entre os novos objetos já estão em vigor). Eu mesmo inventei o termo construtores coletivos, porque nunca ouvi falar desse recurso, mas é possível que exista um nome aceito para esse conceito.
Então, existe alguma linguagem de programação suportando esse tipo de construtores? Caso contrário, a idéia já foi testada?
factory
padrão.A with B
composição de tipo de estilo suportada , cujo construtor resultante essencialmente construiu o novo tipo composto pelas duas características.Respostas:
Isso me parece o padrão Builder , que é uma forma mais complexa de uma fábrica. Um exemplo de Java é um StringBuilder , que você usa para criar uma String e, em seguida, chama
builder.toString()
quando deseja o resultado imutável. No entanto, você pode usar o padrão do construtor para criar coleções de objetos não homogêneas mais complexas. Você pode usar afriend
semântica em um construtor para obter acesso a variáveis privadas que seriam consideradas imutáveis após a criação do objeto de resultado.Linguagens funcionais podem fornecer alguma inspiração. Scala, por exemplo, possui um ListBuffer mutável que pode ser usado para o estágio de construção e, em seguida, convertido em uma lista imutável .
Outro conceito possivelmente relevante é o Freezable Objects , pelo qual um objeto é considerado mutável até que um
Freeze()
método seja chamado. Um construtor pode usar os objetos descongelados e congelá-los antes de retornar.fonte
Ruby, Smalltalk, Self, Newspeak etc. não têm construtores, apenas possuem uma convenção de nomenclatura para métodos de fábrica (por exemplo,
new
em Ruby). Como são apenas métodos padronizados como qualquer outro método, eles podem fazer o que quiserem, incluindo alocar e inicializar quantos objetos quiserem. O principal problema é que esses métodos de fábrica retornam, por convenção, um único objeto que é uma instância da classe na qual o método de fábrica foi chamado. Ou seja, ao chamarFoo.new
, espera-se que você retorne um único objeto que é uma instância doFoo
. Mas, com documentação suficiente, você pode retornar alguma estrutura (por exemplo, umaArray
) de vários novos objetos.Exemplo:
No ECMAScript, construtores são apenas procedimentos regulares, ou melhor, qualquer procedimento pode ser usado como construtor apenas colocando a
new
palavra - chave na frente dele. Novamente, como são apenas procedimentos regulares, eles podem fazer o que quiserem.fonte
Dependências cíclicas entre os objetos? Então a resposta é "não use (apenas) um construtor", porque as chamadas de método cíclico não fazem nenhum sentido. Em vez disso, este é um cenário clássico para alguns métodos de fábrica .
Aqui está um exemplo (em PHP) que é meio bobo, mas ilustra a idéia geral: Você não pode criar um
Sprocket
sem um associadoWidget
e vice-versa. Cada objeto tem uma referência ao outro quando ele se torna disponível.Se eu tivesse que fazer isso no PHP 5.2 na vida real, simplesmente deixaria os construtores públicos e diria às pessoas para não usá-los . Em vez disso, eu teria uma
makeWidgetWithSprocket()
função. Se a linguagem fosse Java, eu usaria seus controles de visibilidade no nível do pacote para evitar erros.Leitura adicional:
create()
, considere o padrão Construtor .fonte