Существует ли шаблон проектирования для структур объектов данных, которые часто меняются?

#design-patterns

#шаблоны проектирования

Вопрос:

Существует ли шаблон проектирования для структур объектов данных, которые часто меняются?

Я занимаюсь рефакторингом генетического алгоритма, в котором структура хромосом (количество генов, тип генов и границы генов) меняется от проблемы к проблеме. Например:

Одна проблема может использовать

 class Chromosome{
    double gene1;  // 0.0 < gene1 < 100.0
    double gene2;  // -7.3 < gene2 < 9.0
}
  

Другая проблема может использовать

 class Chromosome{
    int gene1;      // 200 < gene1 < 1000
    double gene2;  // 50.0 < gene2
    double gene3;  // gene3 < -5.0
}
  

В настоящее время структура хромосом жестко запрограммирована, и ее трудно изменить для решения новой задачи. Я рассматриваю возможность изменения шаблона стратегии для изменений хромосом, если у кого-то нет лучшей идеи.

Ответ №1:

Если хромосомы представляют собой просто набор генных объектов, с ними становится легче работать, особенно если граница также рассматривается как объект.

 public class Gene
{
    public string Id { get; set; }
    public double Value { get; set; }
    public Boundary Boundary { get; set; }
}

public class Boundary
{
    public double? Minimum { get; set; }
    public double? Maximum { get; set; }
}

public class Chromosome
{
    public string Name { get; set; }
    public List<Gene> Genes { get; set; }
}
  

Тогда можно создать новый экземпляр хромосомы, просто снабдив его списком необходимых генов…

  var chromosome1 = new Chromosome
     {
        Name = "Biggie",
        Genes = new List<Gene>
                {
                  new Gene {Id = "1", Boundary = new Boundary {Minimum = 0, Maximum = 100}},
                  new Gene {Id = "2", Boundary = new Boundary {Minimum = -7.3, Maximum = 9}}
                }
     };

 var chromosome2 = new Chromosome
      {
             Name = "Fusion",
             Genes = new List<Gene>
             {
                new Gene {Id = "1", Boundary = new Boundary {Minimum = 200, Maximum = 1000}},
                new Gene {Id = "2", Boundary = new Boundary {Minimum = 50}},
                new Gene {Id = "3", Boundary = new Boundary {Maximum = -5}}
              }
      };
  

Поскольку все хромосомы теперь имеют одинаковую структуру, становится относительно тривиальным сделать создание хромосом управляемым данными. Определения хромосом могут храниться в файле конфигурации или базе данных, а новые могут добавляться по мере необходимости. Каждый объект хромосомы может быть заполнен с помощью простого цикла, который считывает список содержащихся в нем генов.

Комментарии:

1. Это решение не будет работать. Тип значения гена не всегда двойной. Он может быть двойным, целочисленным, логическим или перечисляемым. Также, если существует два гена, каждый ген может иметь другой тип для значения.

2. Все это поместится в double. Вы также могли бы ввести дженерики, но это может не стоить затраченных усилий.

3. Отсутствие математической поддержки сделало дженерики более трудоемкими, чем они того стоили. Решил использовать Double с min, max и increment. Я буду использовать адаптер между значением гена и его интерпретацией.

Ответ №2:

Благодаря помощи dbugger я полагаю, что у меня есть решение. Я оставил идентификатор и границу для простоты. Классы IGene и Gene являются решением. TestGene — это тестовая реализация.

 public interface IGene<T>{
    //Accessors
    public T            getValue();

    public void         setValue(T value);
}

public class Gene<T> implements IGene<T> {
    //Attributes
    T           _value;

    //Accessors
    public T            getValue(){ return this._value;}

    public void         setValue(T value){  this._value = value; }
}

import java.util.ArrayList;
import java.util.List;

public class TestGene {
    public enum EnumType {VALUE1, VALUE2}

    public TestGene() {
        IGene gene;

        List<IGene> chromosome = new ArrayList();

        gene= new Gene<Double>();
        gene.setValue(1.08);
        chromosome.add(gene);

        gene = new Gene<Integer>();
        gene.setValue(3);
        chromosome.add(gene); 

        gene = new Gene<EnumType>();
        gene.setValue(EnumType.VALUE1 );
        chromosome.add(gene);   

        for (int i = 0; i < chromosome.size(); i   ){
            System.out.println( chromosome.get(i).getValue() );
        }
    }