2014-09-27 5 views
3

Я работаю над реализацией сотовой автомата, основанной на Java (не уверен, что это технически, учитывая то, что следует), в котором отдельные ячейки могут иметь разные типы, которые инкапсулируют разные данные и CA правила. Там может быть большое количество типов, и я хочу иметь возможность динамически подключать новые, без необходимости поддерживать другой код.Java: сотовые автоматы с типизированными ячейками

Все типы клеток получены из общего базового класса. Обновление каждой ячейки() метод вызывается только один раз в рамках моделирования:

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); 
      } 
     } 
    } 
} 

Я бы предпочел, чтобы избежать вонючей InstanceOf, если это возможно. Я также не могу просто продвигать getData() в суперкласс для достижения полиморфизма, поскольку фактическая структура данных этих ячеек будет несколько более сложной и разнообразной. Я читал о шаблоне GoF Visitor, чтобы решить instanceof злоупотребления, но я не могу понять, как применить его к этой проблеме. Мысли о том, как это сделать, или о других способах решения проблемы?

Спасибо! Steve

+0

Кажется, что взаимодействие не является частью ни одной ячейки. Возможно, поместите его в другой отдельный класс и передайте все пары (соседних) ячеек? – sje397

+0

Я вижу, что вы говорите о взаимодействии, которое действительно не принадлежит ни одной из ячеек, но если бы это было сделано, я бы не закончил использовать instanceof в огромном операторе switch, чтобы определить все перестановки взаимодействия? И не должен ли клиент-исполнитель модифицировать или расширять этот класс для определения новых взаимодействий? Или я неправильно интерпретирую вас? –

+0

Я бы написал отдельный класс для кода в каждом случае коммутатора и поместил его в коллекцию. Затем у меня будет какая-то функция фильтрации для каждого из них, которая позволяет указать, к каким типам ячеек относится взаимодействие. Это не совсем ускользает от вашей проблемы, но она будет довольно чистой. Это может помочь: http://stackoverflow.com/questions/2722343/java-select-from-collection-only-elements-of-provided-type – sje397

ответ

2

Я играл, и не мог понять, как вы сделали бы шаблон посетителя. A) аккуратно разобраться с двумя пунктами для посещения и b) быть подключаемым, как вам нужно.

Это работает, но, вероятно, скрывает instanceof внутри гуавы материал:

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); 
     } 
    } 
} 

P.S. Вы имели в виду использовать |= при присвоении значения State в цикле?

+0

Спасибо! Независимо от того, использую ли я Guava или нет, это дает мне четкое представление о том, как я могу «скрыть» экземпляр на один комментарий пользователя2864740 выше. –

+1

И я действительно хотел использовать | =, но это было довольно произвольно - оно не отражает фактические операции. –