2015-04-01 4 views
0

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

Например, я могу идентифицировать здания по ID, поэтому у меня может быть гигантский переключатель или командный шаблон внутри класса типа здания. Но я думаю, что с этим подходом что-то не так.

Другой подход состоит в том, чтобы иметь различный класс для любой расходящейся логики. Но это предлагает много маленьких классов.

ответ

1

Это то, что должен решить полиморфизм, и одно из больших различий между процедурным и программированием. Вы можете достичь этого путем расширения базового класса или путем реализации интерфейса. Здесь расширяет базовый класс:

public abstract class Building { 
    abstract void destroy(); 
} 

public BrickBuilding extends Building { 
    @Override 
    public void destroy() { 
     bricks.fallToGround(); 
    } 
} 

public HayBuilding extends Building { 
    @Override 
    public void destroy() { 
     straw.blowInWind(); 
    } 
} 

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

public class BuildingDestroyer { 
    public void rampage() { 
     for(Building building : allTheBuildings) { 
      // Could be a BrickBuilding, or a HayBuilding 
      building.destroy(); 
     } 
    } 
} 

Или, на ваш вопрос о том, много мелких видов, вы можете «внедрить» в destroy поведение, которое вы хотите в общий тип здания, как и ... albeing, вы будете в конечном итоге с много разных классов поведения по-разному ... так что это может быть не решение.

public interface DestroyBehaviour { 
    void destroy(Building building); 
} 

public class Building { 
    private int id; 
    public DestroyBehaviour destroyBehaviour; 

    public Building(int id, DestroyBehaviour destroyBehaviour) { 
     this.id = id; 
     this.destroyBehaviour = destroyBehaviour; 
    } 

    public void destroy() { 
     destroyBehaviour.destroy(this); // or something along those lines; 
    } 
} 
1

Вы можете избавиться от гигантского выключателя, имея класс BuildingFactory, который выставляет registerBuildingType (TYPENAME, instanceCreatorFunc) метод, что каждое здание класса вызовов (от статического метода инициализации, например), и что вызывается с уникальная строка для этого класса (достаточно имя класса) и статический метод «create», который возвращает новый экземпляр.

Этот подход также имеет то преимущество, что он может загружать новые здания из динамически связанных библиотек.

Смежные вопросы