Como lidar com diferentes configurações com propriedades não sobrepostas?

5

Estou trabalhando em um projeto baseado na tecnologia Java EE. Primeiro eu gostaria de te dizer o que eu quero alcançar, então o que eu já tentei.

Tarefa:

Imagine dois tipos de configurações, que você deseja escolher e editar / definir no aplicativo JEE por meio de entradas de GUI. Config A é para a comunicação com o Sistema A e Config B é para a comunicação com Sistema B .

Config A tem algumas propriedades iguais a Configuração B , mas as próprias propriedades diferem de alguma forma (exemplo: enumerações). Além disso, o Config A e B tem cada um mais propriedades que eles não têm em comum. Agora, se o usuário do aplicativo inserir uma configuração (A ou B), deverá ser possível acessar de maneira geral e fácil todos os métodos / propriedades fornecidos das configurações, sem sempre perguntar qual tipo de configuração foi escolhido. Como se pode acessar especialmente as propriedades / métodos que diferem, de maneira fácil e não redundante?

Configuração atual:

Como tento reduzir o código redundante, criei uma classe abstrata definindo uma configuração geral, vamos chamá-la de " GeneralConfiguration ".

Configuração A e B cada extensão Configuração geral . Para cada propriedade "compartilhada", GeneralConfiguration define uma interface. Cada interface foi implementada por diferentes enums, que representam as entradas possíveis para a configuração geral, dependendo do tipo de configuração (A ou B).

Acho que minha configuração não é ideal. Então, o que você acha, como lidar com esse tipo de tarefa?

    
por qecce 22.07.2016 / 14:22
fonte

2 respostas

3

Eu acho que a pergunta é interessante. Não é o problema em si. É devido ao uso indevido de herança. Um uso incorreto muito comum.

Por que eu digo isso?

Because I try to reduce redundant code I created an abstract class defining a general configuration, let's call it "GeneralConfiguration".

Esse é um dos piores motivos para usar a herança. O objetivo por baixo das classes abstratas é muito mais sofisticado do que nos salvar da duplicação de código .

For each "shared" property GeneralConfiguration defines an interface

Aqui, os detalhes de implementação foram transferidos para algo que deve ser abstract . Isso mata o que as classes abstratas fazem bem, abstrai-nos dos detalhes.

A única coisa em comum entre A e B é que, conceitualmente , ambas são configurações , mas aqui terminam suas semelhanças.

Como é isso?

Now, if the application user enters one configuration(A or B) it should be possible to access in a general and easy way all given methods/properties of the configurations.

Por design, ambos se transformaram em algo diferente. Ambos foram projetados como dois componentes diferentes e, agora, estamos tentando corrigi-lo com herança. A herança não funciona dessa maneira.

No papel, ambos podem ter o mesmo significado e propósito, mas esse recurso não foi transferido para o design.

Se quisermos nos abstrair dos "detalhes" (A ou B), a configuração deve ser totalmente agnóstica para eles .

Exemplo:

public Configuration {
  Map<enum,Object> properties;

  public Configuration(){
        properties = new HashMap<enum,Object>();
  }

  public Object getProperty(enum propertyName){
         return properties.get(propertyName);
  }

  public void setProperty(enum propertyName, Object value){
        properties.put(propertyName, value);
  }
 }

Agora, não há A nem B (e a herança se torna desnecessária) .

Como implentamos A e B?

Agora, podemos implementar "detalhes" sobre a abstração. Por exemplo, implementando o padrão de delegação

public ConfigA {
    Configuration config;

  public ConfigA(Configuration config){
      this.config = config;
  }

 public String getA(){
       return (String)  config.getProperty(MyEnumA.A);
  }

  public void setA(String value){
      config.setProperty(MyEnumA.A,value);
  }
      ...
}

Se precisarmos de "detalhes", usamos ConfigA / ConfigB . Nós usamos Configuração para o resto.

Nota: Quando digo abstração , não estou me referindo apenas a classes abstratas. Estou me referindo ao conceito.

    
por 19.11.2016 / 21:39
fonte
0

Acho que o padrão Builder pode ajudar você.

public class ConfigBuilder 
{
    public void SetPropertyA(string a)
    public void SetPropertyB(int b)
    public GeneralConfiguration Build()
}

A interface do usuário pode interagir com os métodos expostos pelo objeto ConfigBuilder . Quando o usuário estiver OK, o método Build será chamado para determinar se ConfigA ou ConfigB será criado com base nas propriedades definidas no objeto ConfigBuilder .

    
por 22.07.2016 / 14:51
fonte