본문 바로가기

정리 카테고리/토비s Spring Vol.1

[동영상 시청/메모]토비의 봄 TV 1회 - 재사용성과 다이나믹 디스패치, 더블 디스패치_3

Toby Lee - 토비의 봄 TV 1회 - 재사용성과 다이나믹 디스패치, 더블 디스패치

42:00~1:09:00

https://youtu.be/s-tXAHub6vg?t=1h9m




*예제 (저번글 마지막)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
static abstract class CallService{//추상 클래스
    abstract void talkToMe();
}
 
static class MyService extends CallService{//상속
    @Override //서브 크래스에서 다시 정의시 붙이도록 권장함
    void talkToMe(){
        System.out.println("Hi");
    }
}
 
static class MyService2 extends CallService{//상속2
    @Override//서브 크래스에서 다시 정의시 붙이도록 권장함
    void talkToMe(){
        System.out.println("Hi2");
    }
}
 
public static void main(String[] args){
    List<CallService> svc = Array.asList(new MyService(), new MyService2());
    //어느 Class의 오브젝트가 들어갈지 한눈에 안보이게 된다.
    svc.forEach(CallService::run);//메소드 레퍼런스
    //타입이 일치하면 가져다 쓸수 이
}
cs

코드작성-https://colorscripter.com




-forEach 는 Consumer interface 타입을 받는 method


-variance :: 변화

-covariance :: 공분산

-contravariance :: 반공분산

-invariance :: 불변성



 -Double Dispatch   ~ Dynamic Dispatch를 2번




*예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Text Picture 를 Facebook 이나 Twitter에 올리는 
// 기능이라는 가정하에 작성된 코드
public class Dispatch{
    interface Post {void postOn( SNS sns );}
    static class Text implements Post{
        public void postOn(SNS sns){
            System.out.println("text ->" + sns.getClass().getSimpleName());
        }
    }
    static class Picture implements Post{
        public void postOn(SNS sns){
            System.out.println("picture ->" + sns.getClass().getSimpleName());
        }
    }
 
    interface SNS {}
    static class Facebook implements SNS{
    };
    static class Twitter implements SNS{
    };
    
    //메인 메소드
    public static void main(String[] args){
        List<Post> posts = Array.asList(new Text(),new Picture());    
        List<SNS> sns = Array.asList(new Facebook(),new Twitter());
 
        for(Post p : posts) {
            for(SNS s : sns) {
                p.postOn(s);
            }
        }
    }
 
    
}
cs

코드작성-https://colorscripter.com



*예제 (위 예제와 같은 결과 나옴)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// Text Picture 를 Facebook 이나 Twitter에 올리는 
// 기능이라는 가정하에 작성된 코드
public class Dispatch{
    interface Post {void postOn( SNS sns );}
    static class Text implements Post{
        public void postOn(SNS sns){
            System.out.println("text ->" + sns.getClass().getSimpleName());
        }
    }
    static class Picture implements Post{
        public void postOn(SNS sns){
            System.out.println("picture ->" + sns.getClass().getSimpleName());
        }
    }
 
    interface SNS {}
    static class Facebook implements SNS{
    };
    static class Twitter implements SNS{
    };
    
    //메인 메소드
    public static void main(String[] args){
        List<Post> posts = Array.asList(new Text(),new Picture());    
        List<SNS> sns = Array.asList(new Facebook(),new Twitter());
 
        posts.forEach(p->sns.forEach(s->p.postOn(s)));
    }
 
    
}
 
cs

코드작성-https://colorscripter.com


-위의 어느 메소드가 실행될지는 컴파일 시점에 정해지는 것이 아니라 런타임 시점에

 들어오는 오브젝트를 보고 결정한다.


*예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Text Picture 를 Facebook 이나 Twitter에 올리는 
// 기능이라는 가정하에 작성된 코드
public class Dispatch{
    interface Post {void postOn( SNS sns );}
 
//이번에 이렇게 쓴이유는 각 경우마다 돌아가야 되는
//정보가 복잡하고 각기 다르다는 가정하에 작성한 것
    static class Text implements Post{
        public void postOn(SNS sns){
            if(sns instanceof Facebook) {
                System.out.println("페북 텍스트");
            }
            if(sns instanceof Twitter) {
                System.out.println("트윗 텍스트");
            }
        }
    }
    static class Picture implements Post{
        public void postOn(SNS sns){
            if(sns instanceof Facebook) {
                System.out.println("페북 픽쳐");
            }
            if(sns instanceof Twitter) {
                System.out.println("트윗 픽쳐");
            }
        }
    }
 
    interface SNS {}
    static class Facebook implements SNS{
    };
    static class Twitter implements SNS{
    };
    
    //메인 메소드
    public static void main(String[] args){
        List<Post> posts = Array.asList(new Text(),new Picture());    
        List<SNS> sns = Array.asList(new Facebook(),new Twitter());
 
        posts.forEach(p->sns.forEach(s->p.postOn(s)));
    }
 
    
}
 
cs

코드작성-https://colorscripter.com




-위 소스의 문제점이 있다.

-오브젝트 타입을 판변하는데 있어 if문을 사용했다는 것. 

  if문을 항목이 추가될때 마다 작성해 주어야 되는데 이를 깜박하게 될수 있다.

  복잡하게 작성된 코드에서 놓치고 가게되면 오류가 발생하게 된다.



-이 문제와 관련된 논문(A Simple Technique for Handling Multiple Polymorphism. -1986년 논문)












*예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Text Picture 를 Facebook 이나 Twitter에 올리는 
// 기능이라는 가정하에 작성된 코드
public class Dispatch{
    interface Post {
        void postOn(SNS sns); 
    }
 
    static class Text implements Post{
        public void postOn(SNS sns){
            public void postOn(SNS sns){
                sns.post(this);
            }
        }
    }
 
    static class Picture implements Post{
        public void postOn(SNS sns){
            public void postOn(SNS sns){
                sns.post(this);
            }
        }
    }
 
    interface SNS {
        void post(Text post);
        void post(Picture post);
    }
 
    static class Facebook implements SNS{
        public void post(Text post) { System.out.println("페이스북 텍스트");}
        public void post(Picture post) { System.out.println("페이스북 픽쳐");}
    };
    static class Twitter implements SNS{
        public void post(Text post) { System.out.println("트위터 텍스트");}
        public void post(Picture post) { System.out.println("트위터 픽쳐");}
    };
    
    //메인 메소드
    public static void main(String[] args){
        List<Post> posts = Array.asList(new Text(),new Picture());    
        List<SNS> sns = Array.asList(new Facebook(),new Twitter());
 
        posts.forEach(p->sns.forEach(s->p.postOn(s)));
    }
 
    
}
 
cs

코드작성-https://colorscripter.com


-이전 코드들과 다른점은 Post를 건드리지 않고 다른(Google 플러스 등등....)

    Class를 추가 할수 있다.(객체지향 스러워짐)

-비지터 패턴보다 더 근본적 모습

-이전 예제에서 안됬던 이유는 Dynamic한 진행을 위해 조건을 파라미터에 걸려고 했기때문

-p 메소드 실행되었을때 파라미터는 Dynamic Dispatch의 조건이 되지 않음

-(자바는 싱글 Dispatch 언어라고 한다. 리시버가 하나.)

-리시버가 하나 ~ 어떤 메소드를 고를때 조건이 1개

-파라미터는 컴파일 시점에 정해져 있지 않으면 진행이 되지 않음.