Skip to content

Commit 5d84448

Browse files
authored
add : study about Adapter (#66)
* add : study about Adapter * fix:오타수정
1 parent e655ec9 commit 5d84448

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

디자인패턴/Adapter.md

+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# 어댑터 패턴
2+
3+
## 📌 어댑터 패턴이란?
4+
5+
- 호환성이 없는 기존 클래스의 인터페이스를 변환하여 사용자가 기대하는 인터페이스 형태로 변환시키는 패턴이다.
6+
- 예) 전기 플러그 → 나라마다 서로 다른 플러그의 경우 어댑터를 사용하여 변환시킬 수 있다.
7+
8+
![Untitled](https://user-images.githubusercontent.com/85864699/213905334-f5fbaa48-53e0-445f-bdd4-829b7c206528.png)
9+
10+
- 코드의 재활용성이 증가하고 기존의 코드를 수정하지 않아도 된다는 장점이 있다.
11+
12+
## 📌 언제 사용할까?
13+
14+
- 외부 구성요소를 기존 시스템에서 재사용하고 싶지만 호환되지 않는 경우에 사용한다.
15+
- 애플리케이션이 클라이언트가 기대하는 인터페이스와 호환되지 않는 경우에 사용한다.
16+
- 원본 코드를 수정하지 않고 애플리케이션에서 레거시 코드를 재사용하려는 경우에 사용한다.
17+
18+
## 📌 어댑터 패턴의 요소
19+
20+
- 문제 상황 : 사용 객체의 API가 서로 다르다.
21+
- 해결 방안 : 함수를 변환하는 객체를 중간에 넣는다.
22+
- 결과 : 변경을 최소화 한다.
23+
- 예시
24+
- 가정1 : 기존 소프트웨어 시스템에서 새로운 업체에서 제공한 클래스 라이브러리를 사용해야한다.
25+
26+
![Untitled](https://user-images.githubusercontent.com/85864699/213905336-d7a6d603-684b-4933-b323-aa73500a849e.png)
27+
28+
해결방안 : 기존 코드를 바꿀 수 없다면 업체에서 사용하는 인터페이스를 기존에 사용하던 인터페이스에 적용시켜주는 클래스를 만들어 사용한다. 이 경우 어댑터는 클라이언트로부터 요청을 받아서 업체에서 제공하는 클래스에서 수용할 수 있는 형태로 변환시켜주는 중개인 역할을 한다.
29+
30+
![Untitled](https://user-images.githubusercontent.com/85864699/213905340-fa7bc606-5785-4904-ba1f-80892124ee38.png)
31+
32+
33+
## 📌 [예시 1] 오리의 탈을 쓴 칠면조
34+
35+
### Duck interface & Mallard Duck class
36+
37+
```java
38+
public interface Duck {
39+
public void quack();
40+
public void fly();
41+
}
42+
43+
public class MallardDuck implements Duck {
44+
public void quack() {
45+
System.out.println("Quack");
46+
}
47+
public void fly() {
48+
System.out.println("I'm flying");
49+
}
50+
}
51+
```
52+
53+
### Turkey interface & WildTurkey class
54+
55+
```java
56+
public interface Turkey {
57+
public void gobble();
58+
public void fly();
59+
}
60+
61+
public class WildTurkey implements Turkey {
62+
public void gobble() {
63+
System.out.println("Gobble gobble");
64+
}
65+
public void fly() {
66+
System.out.println("I'm flying a short distance");
67+
}
68+
}
69+
```
70+
71+
**Duck 객체가 모자라서 Turkey 객체를 대신 사용해야하는 상황에서 어떻게 어댑터를 구현할 수 있을까?**
72+
73+
```java
74+
public class TurkeyAdapter implements Duck {
75+
Turkey turkey;
76+
public TurkeyAdapter(Turkey turkey) {
77+
this.turkey = turkey;
78+
}
79+
public void quack() {
80+
turkey.gobble();
81+
}
82+
public void fly() {
83+
for (int i = 0; i < 5; i++) {
84+
turkey.fly();
85+
}
86+
}
87+
}
88+
```
89+
90+
아래는 TurkeyAdapter를 사용하는 모습을 도식화한 그림이다.
91+
92+
![Untitled](https://user-images.githubusercontent.com/85864699/213905344-843f2efa-933c-4109-a4d3-d91e7f72b3b1.png)
93+
94+
```java
95+
public class DuckTestDrive {
96+
public static void main(String[] args) {
97+
MallardDuck duck = new MallardDuck();
98+
WildTurkey turkey = new WildTurkey();
99+
Duck turkeyAdapter = new TurkeyAdapter(turkey);
100+
101+
System.out.println("The Turkey says…");
102+
turkey.gobble();
103+
turkey.fly();
104+
System.out.println("\nThe Duck says…");
105+
testDuck(duck);
106+
System.out.println("\nThe TurkeyAdapter says…");
107+
testDuck(turkeyAdapter);
108+
}
109+
static void testDuck(Duck duck) {
110+
duck.quack();
111+
duck.fly();
112+
}g
113+
}
114+
```
115+
116+
## 📌 [예시 2] 안드로이드에서 어댑터 패턴 (참고로만 보세요!)
117+
118+
- 안드로이드에서의 어댑터는 뷰(Client)와 데이터 셋(Adaptee) 연결해주는 역할을 한다.
119+
- 어댑터는 데이터 아이템에 접근할 수 있도록 하며, 데이터 셋 속 아이템의 뷰를 그리는 역할도 담당한다.
120+
121+
![Untitled](https://user-images.githubusercontent.com/85864699/213905346-43b7ac47-7a8d-4e95-8647-f2179434fa51.png)
122+
123+
- 예를 들어 저런 리스트 목록 화면을 만든다고 가정하면 데이터를 올리는 부분에서 뷰와 데이터를 연결해주는 다리 역할을 하는 것이 어댑터이다.
124+
- data ← Adapter → AdapterView의 흐름으로 이루어져 있다.
125+
- 안드로이드 코드 예시
126+
127+
![Untitled](https://user-images.githubusercontent.com/85864699/213905349-23e805c8-711f-4ad8-ac2f-643cdb996c76.png)
128+
129+
![Untitled](https://user-images.githubusercontent.com/85864699/213905353-3842de9c-2492-4e0a-9c4b-a32a54ead48d.png)
130+
131+
- 리스트 뷰에 들어가는 아이템들을 나타내는 xml파일인 rv_item.xml
132+
133+
```java
134+
<LinearLayout
135+
xmlns:android="http://schemas.android.com/apk/res/android"
136+
android:layout_width="match_parent"
137+
android:layout_height="match_parent">
138+
139+
<TextView
140+
android:text="rv"
141+
android:textSize="20sp"
142+
android:layout_margin="20dp"
143+
android:layout_width="wrap_content"
144+
android:layout_height="wrap_content"/>
145+
146+
</LinearLayout>
147+
```
148+
149+
- 데이터들이 모아져 있는 List가 있는 [MainActivity.](http://MainActivity.java)kt 파일
150+
- 여기서는 데이터 관리 뿐만 아니라 리사이클러뷰(리스트뷰라고 생각하면 됩니다)와 어댑터를 연결한다.
151+
152+
```java
153+
class MainActivity : AppCompatActivity() {
154+
override fun onCreate(savedInstanceState: Bundle?) {
155+
super.onCreate(savedInstanceState)
156+
setContentView(R.layout.activity_main)
157+
158+
val items=mutableListOf<String>()
159+
items.add("a")
160+
items.add("b")
161+
items.add("c")
162+
163+
//activity_main에 있는 RecyclerView와 연결
164+
val rv=findViewById<RecyclerView>(R.id.rv)
165+
val rvAdapter=RVAdapter(items)
166+
rv.adapter=rvAdapter
167+
168+
rv.layoutManager=LinearLayoutManager(this)
169+
}
170+
}
171+
```
172+
173+
- 아이템들이 들어있는 rv_item.xml과 MainActivity의 list안에 있는 데이터들을 연결해주는 RVAdapter.java
174+
175+
```java
176+
class RVAdapter(val items:MutableList<String>):RecyclerView.Adapter<RVAdapter.ViewHolder>(){
177+
178+
// 리사이클러뷰의 아이템 불러오기
179+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RVAdapter.ViewHolder {
180+
val view=LayoutInflater.from(parent.context).inflate(R.layout.rv_item,parent,false)
181+
// 뷰 홀더에 뷰 넣어주기
182+
return ViewHolder(view)
183+
}
184+
185+
override fun onBindViewHolder(holder: RVAdapter.ViewHolder, position: Int) {
186+
holder.bindItem(items[position])
187+
}
188+
189+
//전체 리사이클러뷰의 개수
190+
override fun getItemCount(): Int {
191+
return items.size
192+
}
193+
194+
//뷰 홀더 만들기
195+
inner class ViewHolder(itemView: View) :RecyclerView.ViewHolder(itemView){
196+
fun bindItem(item:String){
197+
//item은 onBindViewHolder에서 넘겨준 items[postion]값 즉, 리스트 안의 원소들 (a,b,c)
198+
val rv_text=itemView.findViewById<TextView>(R.id.rvItem)
199+
rv_text.text=item
200+
}
201+
}
202+
203+
}
204+
```
205+
206+
207+
## 참고 자료
208+
209+
[https://dev-cini.tistory.com/27](https://dev-cini.tistory.com/27)
210+
211+
[https://wellsw.tistory.com/240](https://wellsw.tistory.com/240)
212+
213+
[https://codingsmu.tistory.com/59](https://codingsmu.tistory.com/59)
214+
215+
[https://velog.io/@haero_kim/우리는-이미-어댑터-패턴을-알고-있다](https://velog.io/@haero_kim/%EC%9A%B0%EB%A6%AC%EB%8A%94-%EC%9D%B4%EB%AF%B8-%EC%96%B4%EB%8C%91%ED%84%B0-%ED%8C%A8%ED%84%B4%EC%9D%84-%EC%95%8C%EA%B3%A0-%EC%9E%88%EB%8B%A4)
216+
217+
헤드퍼스트 디자인 패턴

0 commit comments

Comments
 (0)