IT_Note

MVVM 아키텍처

 


MVC를 대체하기 위해 만들어진 아키텍처

MVC패턴의 경우 뷰와 컨트롤러가 N:N 구조로 만들어지다 보면 전체적인 구조가 복잡하게 얽히게 되는데, 

이러한 문제를 개선하기 위해 모델과 컨트롤러를 뷰에 종속적인 구조로 구성한 뷰 기준의 아키텍처 이다.

따라서 뷰가 종료되면 뷰컨트롤러와 뷰모델은 같이 사라지게 된다.

 

MVC와 MVVM의 가장 핵심적인 차이점은 MVVM에서 뷰 모델(ViewModel)이라고 불리는 뷰의 추상화를 지원한다는 점이다. 뷰 모델은 "데이터 바인딩(data binding)"이라는 기술을 사용해서 모델의 데이터와 뷰가 그리는 화면상의 데이터의 변경을 중재한다.


 

      


출처 : https://www.sencha.com/blog/ext-js-5-mvc-mvvm-and-more/


 

용어의 구체적인 설명은 다음과 같다.


(M) Model - 어플리케이션에서 사용되는 데이터를 담당한다. "Models"라고 불리는 데이터 집합으로 필드와 데이터로 정의된다. 예를 들어 User 모델은 user-name과 password 필드를 갖는다. 모델은 데이터 패키지를 통해 데이터에 대한 추적을 유지하고 결합(associations)을 통해 다른 모델들과 연결된다. 모델은 일반적으로 그리드 또는 다른 컴포넌트에 데이터를 제공하기 위한 스토어(Store)와 결합하여 사용되며, 또한 validation, conversion 기타 등등 데이터를 취급하다보면 필요할 수 있는 모든 데이터 로직의 이상적인 장소라고 할 수 있다.

 

(V) View - 뷰는 화면에 그려지는 비주얼에 관련된 모든 컴포넌트라고 할 수 있다. 그리드, 트리, 패널 등 화면에 나타나는 모든 것을 뷰라고 생각하면 된다.

 

(C) Controller - 어플리케이션이 작동하기 위해 필요한 뷰 로직을 관리한다. 이에 따라 뷰를 랜더링 하고, 라우팅하거나 모델 인스턴스를 생성하거나 또는 다른 어플리케이션 로직 일부를 수행토록 한다.

 

(VM) ViewModel - 뷰 모델은 뷰로 제공되는 데이터를 특정하여 관리하기 위한 클래스로서 컴포넌트가 바인딩을 처리하거나 데이터 변경에 따라 업데이트 되도록 하는 역할을 담당한다. 이러한 어플리케이션 아키텍처는 코드의 구조화 및 일관성을 부여한다.



 

MVVM아키텍처는 뷰와 뷰모델의 데이터바인딩이 핵심이다. 데이터바인딩을 간단하게 설명하면, 일종의 동기화 개념이다.

View의 데이터를 ViewModel에서 추상화 하고 있다, 즉 모델부분의 로직들은 뷰모델에서 관리할 수 있다는 것이고,

이를 뷰 중심으로 개별적으로 관리가 가능하다는 장점이 있다.



MVVM는 ViewController가 제공된다. 

ViewController은 기존의 MVC Controller와 비슷하지만

전역적으로 모든 뷰를 관리하지 않고 View를 개별적으로 관리한다.




View ViewModel VIewController는 한 묶음이라고 생각하면 이해하기 편하다.

View중심이며, 연관된 View가사라지면 ViewModel과 ViewController도 뒤이어 사라진다.


기존의 MVC객체는 컨트롤러가 모든 뷰를 전역적으로 관리하다보니 관련로직이 쏠리게되어

규모가 커질경우 스파게티소스가 되기 쉬웠지만 MVVM은 이를 개별적으로 관리함으로써 

이를 해결하고, 가독성을 높이는 장점이 있고 이로써 단위테스트를 하기 수월해 진다.





 

프로토타입

JavaScript/이론2017. 10. 30. 17:58



두개의 차이 숙지 필요.



1. __proto__ : 상위에서 물려 받은 객체의 프로토타입에 대한 정보. (prototype link 라고도 함)

 

2. protytpe : 자신을 원형으로 만들어질 새로운 객체들의 속성을 담는 그릇.(대부분의 입문자들이 알고 있는 정의 prototype object)

 

prototype chain : 객체의 생성 과정에서 모태가 되는 프로토타입과의 연결고리가 이어져 상속관계를 통하여 상위 프로토타입으로 연속해서 이어지는 관계를 프로토타입체인이라 한다. 이 연결은 __proto__를 따라 올라가게 된다.

 




스택 예제 MP3플레이어. JAVA



스택사용 예제

큐로 했을경우 뭐가 문제인지 생각해보기



- 사용되는 스택은 총 2개 before 과 next  이전곡 / 다음곡을 담아둘 스택.


- 스택은 클래스배열 형태로 넣어주는데 int num은 곡번호, String info배열은 제목과 가수명


- Scanner 이용해서 조작할 수 있게함. n b s p.


- 이전곡/다음곡이 없을경우 등 상황처리


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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
class St{
    
int num;   //번호
String info []; //제목,내용
 
  public St(int num,String sub,String con) {      
      this.num=num;
      this.info = new String[]{sub,con};      
  }  
  
  @Override
    public String toString() { // 주소값을 내용으로 변환.
        return num + Arrays.toString(info);
    }
  
}
 
 
public class Mp3 {    
    Stack<St> before = new Stack<St>(); // 이전곡
    Stack<St> next = new Stack<St>(); //다음곡
    St now = null//현재곡
            
    
    boolean backchk(){//뒤로가기 로직
        boolean res = !before.empty();//비어있으면, false
        
        if(res){ //이전곡 잇을경우 현재곡을 이전곡으로 설정.
            
            if(now!=null){ //현재곡이 존재할경우 현재곡을 다음곡으로 push
                next.push(now);                
            }             
            now = before.pop(); // ★현재곡은 이전곡으로.            
        }        
        return res;
    }
    
    void backtr(){ //뒤로가기 조작
        System.out.println("← 이전곡 재생버튼");
        
        if(backchk()){    
            print();
        }
        else{
            System.out.println("※※※ 이전곡이 없습니다");
        }
        
    }
    
    boolean nextchk(){        
    boolean res = !next.empty();//다음곡이 비어잇는게 아니면
        
    if(res){// 다음곡 있을경우.
    
        
    if(now!=null){
    before.push(now);
    }
    
    now = next.pop(); //현재곡은 다음곡으로     설정
    }
    
    return res;
    }
    
    void nexttr(){ //다음곡 조작.
    System.out.println("→ 다음곡 재생버튼");
    
    if(nextchk()){//잘 됫을경우
        print();        
    }
    else
        System.out.println("※※※ 다음곡이 없습니다.");
    }
    
    }
    
    void stop(){ //스탑
        System.out.println("곡을 멈춥니다.");
        
        if(now!=null){ //현재곡이 있을경우.
            
            next.push(now); //다음곡에 현재곡 저장.
            now=null;//현재곡은 비움.
            print();
        }else{
            System.out.println("※※※ 실행중인 곡이 없습니다.");
        }
    }
    
    void play(){
        System.out.println("mp3를 시작합니다");
        
        if(now==null){//멈춰 있는 상태일 경우.
            now=next.pop();//now에 다음곡 입력해줌.
            print();
        }else{
            System.out.println("※※※ 이미 실행중입니다");
            print();
        }
        
    }
    
    void play(int num){
    //해당번호 곡 재생하기 미구현    
    }
    
    public Mp3() {//생성자, 내용입력,        
 
        next.push(new St(6"제목6""내용6"));    
        next.push(new St(5"제목5""내용5"));
        next.push(new St(4"제목4""내용4"));
        next.push(new St(3"제목3""내용3"));
        next.push(new St(2"제목2""내용2"));
        next.push(new St(1"제목1""내용1"));
    }
    
    void print(){ //현재상태 출력
        System.out.println("\n이전곡"+before);
        System.out.println("현재곡"+now);
        System.out.println("다음곡"+next+"\n");
    }
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        Scanner sc = new Scanner(System.in);
        Mp3 mp3 = new Mp3();
        
        
        System.out.println("★빠밤~ mp3전원이 켜졌습니다.★ \n 조작방법 - 재생:p/멈춤:s/다음곡:n/이전곡:b 입력");
        while(true){            
        String input = sc.next();    
        
        switch (input) {        
        case "b":
            mp3.backtr();
            break;
            
        case "n":
            mp3.nexttr();
            break;
            
        case "s":
            mp3.stop();
            break;
            
        case "p":
            mp3.play();
            break;
 
        default:
            break;
        }
        
        }
        
        
    }
 
}
 
cs





큐로 했을경우 FIFO이기 때문에,


이전곡 다음곡 이동시에 꼬여버리는 현상이 나타난다.

LIFO같은경우 가장 마지막에 했던것이 POP된다.


FIFO는 가장 근접한 최근곡을 이전곡으로 설정 해야 하는데, 큐로 하게되면

그게 불가능. 걍 처음넘어간 것만