Java:具有类型化单元的细胞自动机

Java:具有类型化单元的细胞自动机,java,polymorphism,cellular-automata,Java,Polymorphism,Cellular Automata,我正在研究一个基于Java的细胞自动机类实现(不确定技术上是否如此,给出了下面的内容),其中单个细胞可能有不同的类型,封装不同的数据和CA规则。可能有很多类型,我希望能够动态地插入新的类型,而不必维护其他代码 所有单元类型都派生自一个公共基类。每个单元的update()方法在模拟的每一帧中只调用一次: public abstract class Cell { public abstract void update(Cell[] neighbors); } 当CA规则只需要相关单元格的数

我正在研究一个基于Java的细胞自动机类实现(不确定技术上是否如此,给出了下面的内容),其中单个细胞可能有不同的类型,封装不同的数据和CA规则。可能有很多类型,我希望能够动态地插入新的类型,而不必维护其他代码

所有单元类型都派生自一个公共基类。每个单元的update()方法在模拟的每一帧中只调用一次:

public abstract class Cell
{
    public abstract void update(Cell[] neighbors);
}
当CA规则只需要相关单元格的数据时,此功能可以正常工作,例如:

public class CellTypeA extends Cell
{
    public int Data = 0;

    @Override
    public void update(Cell[] neighbors)
    {
        Data++;
    }
}
但是,我有一些模拟规则,要求单元查询相邻的相邻单元以获取数据,但前提是这些单元的类型包含上述数据。使用instanceof操作符来实现这一点有很大的诱惑力:

public class CellTypeB extends Cell
{
    public boolean State = false;

    private void update(Cell[] neighbors)
    {
        for (Cell c : neighbors)
        {
            if (c instanceof CellTypeA)
            {
                State = (((CellTypeA)c).getData() > 10);
            }
        } 
    }
}
如果可能的话,我更愿意避免这种气味难闻的情况。我也不能仅仅将getData()提升到超类以实现多态性,因为这些单元的实际数据结构将更加复杂和多样。我一直在阅读关于GoF访问者模式以解决滥用实例的文章,但我似乎不知道如何将其应用于这个问题。思考如何做到这一点,或者思考其他解决问题的方法

谢谢!
Steve

我到处玩,不知道如何让访问者模式a)巧妙地处理两个要访问的项目,b)像您所需的那样可插入

这是可行的,但可能隐藏了番石榴中的
实例:

import com.google.common.collect.Iterables;
import java.util.Arrays;

public class CellTypeB extends Cell
{
    public boolean State = false;

    @Override
    public void update(Cell[] neighbors) {
        Iterable<CellTypeA> onlyAs = Iterables.filter(Arrays.asList(neighbors), CellTypeA.class);
        for(CellTypeA a: onlyAs) {
            State = (a.getData() > 10);
        }   
    }   
}   
import com.google.common.collect.Iterables;
导入java.util.array;
公共类CellTypeB扩展了Cell
{
公共布尔状态=false;
@凌驾
公共无效更新(单元格[]邻居){
Iterable onlyAs=Iterables.filter(Arrays.asList(邻居),CellTypeA.class);
对于(CellTypeA:仅适用于){
State=(a.getData()>10);
}   
}   
}   

另外,在给循环中的
状态
赋值时,您是否打算使用
|=

在我看来,交互作用不是两个单元格的一部分。也许把它放在另一个单独的类中,把所有成对的(相邻的)单元传递给它?我明白你所说的交互并不真正属于任何一个单元,但是如果要这样做,我会不会在一个巨大的switch语句中使用instanceof来定义所有的交互排列?实现客户机不需要修改或扩展这个类来定义新的交互吗?或者我对您的解释不正确?我会在开关的每种情况下为代码编写一个单独的类,并将它们放在一个集合中。然后,我在每一个上面都有一些过滤函数,可以让你指定交互应用于哪些单元格类型。它并不能完全摆脱你的问题,但它会相当干净。这可能会有帮助:另一件需要注意的事情是,如果你在一个类上有方法
operate(Cell c)
operate(cellsublass)
,并且你调用
operate(x)
,java将采用最匹配的派生类型的方法。我可能会保留一种instanceof check形式,可能是隐藏的,并且倾向于接口而不是具体类型。“更多的模式”并不一定更好,必须权衡复杂性与任何好处。将更新移出每个单元格听起来像是一种探索的方法(主要是允许在不改变“哑”单元格数据对象类的情况下应用不同的算法),但这是一项正交任务。我通常不喜欢访问者模式,在这种情况下,我更喜欢手动处理“类型歧视”。谢谢!无论我是否使用番石榴,这让我清楚地知道如何根据上面用户2864740的评论“隐藏”instanceof。我确实想使用|=,但这是相当随意的-它不能代表正在执行的实际操作。