2017-03-17 4 views
0

플레이어 캐릭터가 내 세계 모델에서 캐릭터의 동작 방식을 변경하거나 기능을 추가하는 특성을 얻을 수있는 게임을 만들고 있습니다. 예를 들어, 캐릭터는 추락 손상을 계산하는 방식을 변경하는 "깃털"특성이나 이전에는 경치의 일부였던 아이템을 플레이어가 선택할 수있는 "강한"특성을 얻을 수 있습니다.런타임시 변경 가능한 기능을 구현하는 방법은 무엇입니까?

저는 관련 클래스에서 특성을 하드 코딩하고 작동 할 때 동작을 변경하기 위해 부울을 전환했지만 특성 목록이 커짐에 따라 관리하기가 어려워지고 있습니다. 이 작업을 수행하는 데 확장 성이 있고 분리 된 방식이 있어야합니다.

(내가 원하는 완벽한 시나리오는 클래스 변형을 프로그래밍하고 이전 객체의 컨텍스트와 참조를 유지하면서 런타임에 어떤 방법으로 전환 할 수있는 방법이지만 요구 사항을 적절하게 충족시키는 다른 방법입니다.)

메소드를 변경하고 런타임에 새로운 기능을 얻고 제거하는 방법은 어떻게 구현합니까? (주어진 시나리오에 가상의 예제를 제공하십시오). 이런 종류의 행동을 달성하기 위해 어떤 프로그래밍 패턴을 사용하겠습니까?

추신 : 더 나은 제목을 제안 해주십시오. 나는 그것들을 빨아 먹는다. 더 좋은 것을 찾으면 이것을 편집 할 것입니다.

+0

https://sourcemaking.com/design_patterns/state – jaco0646

답변

1

당신은 원본 객체의 참조를 변경하지 않고, 일반적으로 동적 객체에 동작을 추가하고 제거하는 데 사용되는 Decorator Pattern를 구현을 시도 할 수 있습니다. Wikipedia 페이지에서는 좋은 설명과 예제를 제공합니다. 어쨌든 간단한 자바를 보여 주려고 노력할 것입니다. (당신이 이해할 수 있기를 바랍니다.

public class Character { 

    public int calculateFallDamage() { 
     return 10; 
    } 

    public void pickUpItem() { 
    // initially this method could be empty 
    // nothing happens when you try to pick up items 
    } 
} 

지금 우리는 "깃털"특성을 추가 문자의 서브 클래스를 만들 :이 같은 문자 클래스가 있다고 가정 .

Character character = new Character(); 
int fallDamage = character.calculateFallDamage(); // returns 10 
character = new FeatherDecorator(character); 
int newFallDamage = character.calculateFallDamage(); // returns 5 
: 당신은이 같은 새로운 개체를 만들 수있는 "깃털"특성을 추가하려면

public class FeatherDecorator extends Character { 

    private Character decoratedCharacter; 

    public FeatherDecorator(Character character) { 
     this.decoratedCharacter = character; 
    } 

    @Override 
    public int calculateFallDamage() { 
     int fallDamage = decoratedCharacter.calculateFallDamage(); // call the function of the decorated class 
     return fallDamage - 5; // change the result 
    } 
} 

:이 서브 클래스의 동작을 변경하는 것이 순서 확장하는 클래스의 필드를 포함해야합니다

이런 식으로하면 객체에 대한 원본 참조를 유지할 수 있지만 동시에 그의 행동을 변경할 수 있습니다. 당신이 장식을 제거 관심이 있다면 당신은이 같은 방법을 추가 할 수 있습니다

public class Character() { 
    ... 
    public Character getDecoratedComponent() { 
    // exception becaus it's not decorated 
    } 
    ... 
} 

public class FeatherDecorator extends Character { 

    private Character decoratedCharacter; 
    ... 
    @Override 
    public Character getDecoratedComponent() { 
     return decoratedCharacter; 
    } 
    ... 
} 

을 지금은 장식없이 원래의 객체를 얻기 위해 매우 쉽습니다 :

Character character = new FeatherDecorator(new Character()); 
character = character.getDecoratedComponent(); // returns the object without the feater decorator 

을 내가는 내가 당신을 도움이 희망 데코레이터 패턴은 객체의 동작에 유연성을 제공하는 매우 강력한 패턴입니다. 더 자세한 설명이 필요하면 알려주십시오.

+0

이것은 정확히 두 가지주의 사항으로 원하고 있습니다. 어쩌면 당신도 그것들을 도울 수 있습니다. 이 문제의 첫 번째 문제는 내가 이해하는 한 임의의 수의 특성을 추가 할 수 있다는 것입니다. 예를 들어 깃털 형질을 추가 한 다음 강력한 형질을 추가하면 효과가 있습니다.그러나 내가 특성을 제거하고 싶다면 마지막으로 추가 된 것을 제거 할 수 있습니다. 스택처럼. 두 번째 문제는 문자 개체에 대한 단일 참조가 있다고 가정하는 경우입니다. 한 번에 모든 참조를 업데이트 할 수있는 방법이 있습니까? – Althis

+0

특정 장식을 제거하려면 [이 질문] (http://stackoverflow.com/questions/12239784/how-to-remove-decorated-object-from-decorator-pattern-in-java#)을 참조하십시오. 12240581). 미안하지만 동일한 객체에 대해 여러 가지 다른 참조를 가질 수 있다는 것을 이해하지 못했습니다.이 사실은 데코레이터 패턴에 문제를 일으킬 수 있습니다. 이 경우 _jaco0646_이 주석에서 말한 것처럼 [상태 패턴] (https://sourcemaking.com/design_patterns/state)이 더 나을 수도 있습니다. –

관련 문제