2013-01-14 2 views
1

이 질문은 대표단 디자인 패턴은 here입니다. Java에서 대체 가능성을 잃지 않고 위임 디자인 패턴을 사용하는 방법이 있습니까?

  • 메쉬

    • 플레이어
    • 차량 및 이들 각각을 수행 할 수 있습니다

      나는 다양한 개체를 나타내는 내 게임 엔진의 인터페이스의 번호를 가지고 표현되기 (위해) 때문에, 그들은 render() 메소드를 포함한 Renderable 인터페이스를 구현합니다. 위임을 사용

      방법 1

      는 예는 다음과 같다 : 나는 차를 렌더링 할 때마다, 난 그냥 car.renderable.render(); 전화

      public interface Vehicle { 
      
          public void drive(); 
      
      } 
      
      public class Car implements Vehicle { 
      
          public Renderable renderable; 
      
          @Override 
          public void drive() { // ... } 
      
      } 
      

      .

      이 방법의 문제점은 목록을 만들고 반복 할 수 없다는 점입니다.

      public interface Vehicle extends Renderable { 
      
          public void drive(); 
      
      } 
      

      만이 가진 문제가 있음을 나는 자동차, 자전거, 트럭, 탱크 정의하면, 등 :

      방법이

      이 문제를 해결하기 위해, 나는 차량 렌더링 가능한 확장 할 수 이 클래스들 각각은 render()에 대한 코드를 채워야합니다 (아마도 동일 할 것입니다).

      Vehicle을 구현하는 모든 구체적인 클래스에서 render()를 정의하지 않으면 서 Renderable을 내 Vehicle 인터페이스로 확장하는 이점을 유지할 수있는 방법이 있습니까? render 메서드에 대한 코드가 다른 클래스 사이에 동일 경우

    +0

    이 질문은 여기에서 나온 : http://stackoverflow.com/questions/5546711/how-to-write-solid-pure-aggregation-composition-game-objects-in-java – sdasdadas

    +2

    각 클래스합니까 그 Renderable은'public Renderable getRenderable()'메서드를 가지고 있습니까? 그렇다면이 동물들을 모을 수있는 인터페이스가 될 수 없습니까? 또한이 사람들이 Iterable 인터페이스를 구현하도록 하시겠습니까? –

    +0

    각각에는 'getRenderable()'메소드가 있습니다. 나는 인터페이스를 추출 할 수 있다고 믿는다. (실제로 Renderable 인터페이스에 대한 테스트이기 때문에 무엇을 호출해야할지 모르겠다.) 그리고 아니, 나는 가지 않을거야 ... – sdasdadas

    답변

    2

    ,

    는 렌더링 가능한을 보유하고 각 클래스가 공용 렌더링 가능한 getRenderable() 메소드를 가지고 있는가? 그렇다면이 동물들을 모을 수있는 인터페이스가 될 수 없습니까?

    interface Renderable { 
        void render(); 
    } 
    
    interface RenderDelegator { 
        Renderable getRenderable(); 
        void setRenderable(Renderable renderable); 
    } 
    
    abstract class Vehicle implements RenderDelegator { 
        private Renderable renderable; 
    
        @Override 
        public Renderable getRenderable() { 
         return renderable; 
        } 
    
        @Override 
        public void setRenderable(Renderable renderable) { 
         this.renderable = renderable; 
        } 
    
        public abstract void drive(); 
    } 
    
    class Car extends Vehicle { 
        @Override 
        public void drive() { 
         // TODO finish! 
        } 
    
    } 
    

    와의 Iterable을 구현하는 방법에 대한 괜찬 그 제안 :

    나는 같은 것을 의미했다. 내가 뭘 생각했는지 모르겠다.

    +0

    그건 멋지다. 그리고 내가 필요한 모든 것을 충족시킨다. 고마워요! – sdasdadas

    +1

    @sdasdadas : 환영합니다.하지만 디자인 패턴이 아닙니다. 이 실을 계속 주시하고 더 나은 제안이 나오면 알려 주시고 동의하십시오. –

    +0

    손에있는 새 ... – sdasdadas

    0

    , 다음을 수행하십시오

    Renderable를 구현 AbstractRenderable라는 추상 클래스를 소개합니다. 그런 다음 , Bicycle 등의 클래스를 AbstractRenderable까지 확장하고 Vehicle (또는 Player 등)을 구현하십시오.

    AbstractRenderable 클래스의 경우 render 메서드를 구현하십시오. 그런 식으로 모든 자동차, 자전거 등은 "동일한"렌더링 코드를 사용합니다. 또한 예를 들어 Tank에서 렌더링 코드가 다른 경우 render 메서드를 재정의 할 수 있습니다. 내 댓글에 대해서는

    +0

    이것은 Renderable 이상에서 확장해야 할 때까지 작동합니다 (미안하지만 앞으로 Moveable, Destroyable 등을 추가해야한다고 말했음). – sdasdadas

    1

    또 다른 방법은 Renderable 개체의 개념을 가능한 대리자 렌더러와 분리하는 것입니다. 이런 방식으로, 렌더러 코드가 단일 클래스에 특정한 경우 일반 렌더러에 위임하거나 클래스에서 render() 메소드를 구현할 수 있습니다.

    렌더러는 렌더링하려는 엔티티의 인스턴스를 쿼리해야 할 수도 있습니다. 즉, Vehicle이지도에서 위치를 얻는 방법이 있다고 가정하면 렌더러는 그 값을 가져와 올바른 위치에 렌더링; 그래서 Renderer 인터페이스는 Renderable의 인스턴스를받습니다.

    interface Renderable { 
        void render(); 
    } 
    
    interface Vehicle extends Renderable { 
        void drive(); 
    } 
    
    interface Renderer<T extends Renderable> { 
        void render(T renderable); 
    } 
    
    public class VehicleRenderer implements Renderer<Vehicle> { 
        public void Render(Vehicle renderable) { 
         // TODO: Render a Vehicle. 
        } 
    } 
    
    public class Car implements Vehicle { 
        private Renderer<Vehicle> renderer; 
    
        public void setRenderer(Renderer<Vehicle> renderer) { 
         this.renderer = renderer; 
        } 
    
        public void render() { 
         renderer.render(this); 
        } 
    
        public void drive() { 
         // TODO: Drive the car. 
        } 
    }