22-04-11-비지터패턴-2부-패턴적용하기
본문 바로가기
CS Study/디자인패턴

22-04-11-비지터패턴-2부-패턴적용하기

by KyeongMin 2022. 4. 12.
728x90
반응형

01.비지터패턴 적용하기

01.1 Shape.java

  • before
  • public interface Shape {
        void printTo(Device device);
    }// 모든 디바이스에 쓰기 위함
  • after
  • public interface Shape {
        void printTo(Phone phone);
        void printTo(Watch watch);
    }

01.2 Circle.java

  • before
  • public class Circle implements Shape{
    	@Override
        public void printTo(Device device){
            if(device instanceof Phone){
                System.out.println("print Circle to Phone");
            }else if(device instanceof Watch){
                System.out.println("print Circle to Watch");
            }
        }
    }
  • after
  • public class Circle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Circle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Circle to Watch");
        }
    }

01.3 Retangle.java

  • before
  • public class Rectangle implements Shape{
    	@Override
        public void printTo(Device device){
            if(device instanceof Phone){
                System.out.println("print Rectangle to Phone");
            }else if(device instanceof Watch){
                System.out.println("print Rectangle to Watch");
            }
        }
    }
  • after
  • public class Rectangle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Rectangle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Rectangle to Watch");
        }
    }

01.4 Triangle.java

  • before
  • public class Triangle implements Shape{
    	@Override
        public void printTo(Device device){
            if(device instanceof Phone){
                System.out.println("print Triangle to Phone");
            }else if(device instanceof Watch){
                System.out.println("print Triangle to Watch");
            }
        }
    }
  • after
  • public class Triangle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Triangle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Triangle to Watch");
        }
    }

01.5 Client.java

  • before
    • 위의 클라이언트 코드로 하면 에러가 생기는 이유?
      • Device device 이것이 아무리 폰과 워치의 상위 타입이라고 하더라도
        • 컴파일 타임에서 어떤 타입이될지 모름
        • 런타임 중에 메소드 오버라이딩는 찾을 수 없음
          • 스태틱한 매핑을 해버림
      • 메소드 오버라이딩은 컴파일 타임에 됨
  • public class Client{
        public static void main(String[] args)
        {
            Shape rectangle = new Rectangle();
            Device device = new Phone();
            rectangle.printTo(device);
    	}
    }
  • after
  • public class Client{
        public static void main(String[] args)
        {
            Shape rectangle = new Rectangle();
            rectangle.printTo(new Phone());
    	}
    }

02.제대로 동작하게 패턴 적용

02.1 Shape.java

  • before
  • public interface Shape {
        void printTo(Phone phone);
        void printTo(Watch watch);
    }
  • after
  • public interface Shape {
        void accept(Device device);
    }

02.2 Circle.java

  • before
  • public class Circle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Circle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Circle to Watch");
        }
    }
  • after
  • public class Circle implements Shape{
    	@Override
    	public void accept(Device device){
    		device.print(this);
        }
    }

02.3 Retangle.java

  • before
  • public class Rectangle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Rectangle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Rectangle to Watch");
        }
    }
  • after
  • public class Rectangle implements Shape{
    	@Override
    	public void accept(Device device){
    		device.print(this);
        }
    }

02.4 Triangle.java

  • before
  • public class Triangle implements Shape{
    	@Override
        public void printTo(Phone phone){
            System.out.println("print Triangle to Phone");
        }
        @Override
        public void printTo(Watch watch){
            System.out.println("print Triangle to Watch");
        }
    }
  • after
  • public class Triangle implements Shape{
    	@Override
    	public void accept(Device device){
    		device.print(this);
        }
    }

02.5 Device.java

public interface Device{
    void print(Circle circle);
    void print(Retangle retangle);
    void print(Triangle triangle);
}

02.6 Phone.java

  • before
  • public Phone implements Device{
    }
  • after
  • public Phone implements Device{
        @Override
        public void print(Circle circle){
    		System.out.println("Print Circle to Phone");
        }
        
        @Override
        public void print(Retangle retangle){
    		System.out.println("Print Retangle to Phone");
        }
        
        @Override
        public void print(Triangle triangle){
    		System.out.println("Print Triangle to Phone");
        }    
    }

02.7 Watch.java

  • before
  • public Watch implements Device{
    }
  • after
  • public Watch implements Device{
        @Override
        public void print(Circle circle){
    		System.out.println("Print Circle to Watch");
        }
        
        @Override
        public void print(Retangle retangle){
    		System.out.println("Print Retangle to Watch");
        }
        
        @Override
        public void print(Triangle triangle){
    		System.out.println("Print Triangle to Watch");
        }    
    }

02.8 Client.java

  • before
  • public class Client{
        public static void main(String[] args)
        {
            Shape rectangle = new Rectangle();
            Device device = new Phone();
            rectangle.printTo(device);
    	}
    }
  • after
  • public class Client{
        public static void main(String[] args)
        {
            Shape rectangle = new Rectangle();
            Device device = new Phone();
            rectangle.accept(device);
    	}
    }

03.왜 더블 디스패치라고 하는가?

  • rectangle.accept(device);
    • 여기서 어떤 accept로 찾아가야하는지에 대한 디스패치가 일어남
  • device.print(this);
    • 어떤 디바이스의 print를 써야하는지에 대해서 런타임에서 알아서 또 찾아서 디스패치가 일어남

https://3dpit.github.io/posts/%EB%B9%84%EC%A7%80%ED%84%B0%ED%8C%A8%ED%84%B4-2%EB%B6%80-%ED%8C%A8%ED%84%B4%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0/

 

22-04-11-비지터패턴-2부-패턴적용하기

## 22-04-11-비지터패턴-2부-패턴적용하기

3dpit.github.io

 

728x90
반응형

댓글