Design patterns 是否存在频繁更改的数据对象结构的设计模式?

Design patterns 是否存在频繁更改的数据对象结构的设计模式?,design-patterns,Design Patterns,是否存在频繁更改的数据对象结构的设计模式 我正在重构一个遗传算法,其中染色体的结构(基因数量、基因类型和基因边界)会随着问题的不同而变化。例如: 有一个问题可能需要解决 class Chromosome{ double gene1; // 0.0 < gene1 < 100.0 double gene2; // -7.3 < gene2 < 9.0 } 类染色体{ 双基因1;//0.0

是否存在频繁更改的数据对象结构的设计模式

我正在重构一个遗传算法,其中染色体的结构(基因数量、基因类型和基因边界)会随着问题的不同而变化。例如:

有一个问题可能需要解决

class Chromosome{
    double gene1;  // 0.0 < gene1 < 100.0
    double gene2;  // -7.3 < gene2 < 9.0
}
类染色体{
双基因1;//0.0
另一个问题可能会用到

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

目前染色体结构是硬编码的,很难针对新问题进行修改。我正在考虑修改染色体改变的策略模式,除非有人有更好的想法

如果染色体只是基因对象的集合,它们就更容易处理,特别是当边界也被视为对象时

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; }
}
公共类基因
{
公共字符串Id{get;set;}
公共双值{get;set;}
公共边界{get;set;}
}
公共阶级界限
{
公共双精度?最小值{get;set;}
公共双精度?最大值{get;set;}
}
公共类染色体
{
公共字符串名称{get;set;}
公共列表基因{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}}
              }
      };
var chromosome1=新染色体
{
Name=“Biggie”,
基因=新列表
{
新基因{Id=“1”,边界=新边界{最小值=0,最大值=100},
新基因{Id=“2”,边界=新边界{最小值=-7.3,最大值=9}
}
};
var chromosome2=新染色体
{
Name=“Fusion”,
基因=新列表
{
新基因{Id=“1”,边界=新边界{最小值=200,最大值=1000},
新基因{Id=“2”,边界=新边界{Minimum=50},
新基因{Id=“3”,边界=新边界{Maximum=-5}
}
};

由于所有染色体现在都具有相同的结构,因此使染色体创建数据驱动变得相对简单。染色体定义可以存储在配置文件或数据库中,并根据需要添加新的定义。每个染色体对象都可以通过一个简单的循环来填充,该循环读取它所包含的基因列表。

多亏了dbugger的帮助,我相信我找到了一个解决方案。为了简单起见,我省略了ID和边界。IGene和基因类是解决方案。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() );
        }
    }
公共接口IGene{
//访问者
公共T getValue();
公共无效设置值(T值);
}
公共类基因实现IGene{
//属性
T_值;
//访问者
public T getValue(){返回此值。_value;}
public void setValue(T value){this.\u value=value;}
}
导入java.util.ArrayList;
导入java.util.List;
公共类TestGene{
公共枚举枚举类型{VALUE1,VALUE2}
公共测试基因(){
IGene基因;
列表染色体=新的ArrayList();
基因=新基因();
基因设定值(1.08);
染色体。添加(基因);
基因=新基因();
基因设定值(3);
染色体。添加(基因);
基因=新基因();
gene.setValue(EnumType.VALUE1);
染色体。添加(基因);
对于(int i=0;i
此解决方案将不起作用。基因值的类型并不总是双精度的。它可以是双精度、整数、布尔值或枚举值。此外,如果有两个基因,每个基因的值可能具有不同的类型。所有这些类型都将适合双精度。您也可以引入泛型,但可能不值得这样做。缺乏数学支持e泛型需要做的工作太多了。决定使用Double加上min、max和increment。我将在基因值和它的解释之间使用一个适配器。