Skip to content
This repository was archived by the owner on Jan 13, 2021. It is now read-only.

Commit e356aeb

Browse files
committed
doc: update adapter readme
1 parent 209796d commit e356aeb

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

StructuralPattern/Adapter/README.md

+96
Original file line numberDiff line numberDiff line change
@@ -1 +1,97 @@
1+
## 개요
2+
클래스의 인터페이스를 사용자가 기대하는 인터페이스 형태로 적응(변환)시킵니다. 서로 일치하지 않는 인터페이스를 갖는 클래스들을 함께 동작시킵니다.
13

4+
## 다른이름
5+
래퍼(Wrapper)
6+
7+
## 동기
8+
가끔은 재사용을 목표로 개발한 툴킷도 실제 재사용성을 발휘하지 못할 때가 발생한다. 즉, 응용프로그램이 요청하는 인터페이스와 툴킷에 정의된 인터페이스가 일치하지 않을 때가 있기 때문.
9+
10+
편집기로 예를들면, 그림 편집기는 사용자가 선, 다각형, 텍스트 등 그래픽 요소를 이용하여 그림과 다이어그램을 만들 수 있는 프로그램이다. 그림판의 중요한 개념은 그래픽 객체들인데, 이들은 모양을 편집할 수 있는 특징을 가지며, 화면에 그려질 수 있는 행동을 정의한다. 이러한 공통점을 Shape라는 추상적인 인터페이스로 정의를 해봅시다. 그 후 우리는 편집기의 각각의 그래픽 요소를 Shape의 서브클래스로 정의해야 한다. 즉, 선을 위한 LineShape, 다각형을 위한 PolygonShape 등 클래스를 개발 한다.
11+
12+
LineShape나 PolygonShape 클래스와 같이 아주 기본적인 그래픽 요소들은 제한적인 기능들로 이루어져 있어 구현하기 쉽다. 그러나 TextShape는 텍스트를 처리하기 위해 화면을 수정하고 버퍼를 관리하는 등 복잡한 기능을 구현해야 한다. 그래서 TextShape 클래스를 구현할때는 툴킷에서 제공되는 TextView를 재사용하는것이 바람직 하지만, 기존 구현된 툴킷은 현재 새롭게 개발된 Shape 클래스를 고려해서 개발된 것이 아니므로 바로 TextShape의 대체해 사용할 수 있는 상황이 안된다.
13+
14+
그렇다면 서로 일치하지 않는 인터페이스를 갖는 클래스들을 잘 통합하여 하나의 응용프로그램으로 구성하여 운영해야 할때 어떤 방법이 있을까? 다시 말해 , 기존에 만든 TextView의 인터페이스를 변경해 Shape의 인터페이스와 일치하게 만들 수 있을까? 소스가 있다면 가능할 수 있겠지만 없다면 TextView를 변경하는 것은 불가능 하다.
15+
16+
이미 개발된 클래스의 인터페이스를 수정할 수 없다면, Shape와 TextView 인터페이스에 맞도록 우리가 개발한 TextShape 클래스를 조정을 해야 한다. 이를 위해 우리가 할 수 있는 일은 다음과 같다.
17+
1. Shape의 인터페이스와 TextView의 구현을 모두 상속을 받는다
18+
2. TextView의 인스턴스를 TextShape에 포함시키고, TextView 인터페이스를 사용하여 TextShape를 구현한다.
19+
20+
이들 두 가지 방법은 적응자 패턴의 클래스 버전 및 객체 버전에 해당합니다
21+
22+
## 예제코드
23+
```kotlin
24+
data class Rect(
25+
val x: Int,
26+
val y: Int
27+
)
28+
29+
data class Bound(
30+
val left: Int,
31+
val top: Int,
32+
val right: Int,
33+
val bottom: Int
34+
)
35+
36+
interface Shape {
37+
val width: Int
38+
val height: Int
39+
40+
fun getBound(): Bound
41+
}
42+
43+
interface TextShape : Shape {
44+
fun move(x: Int, y: Int)
45+
fun getText(): String
46+
fun editText(text: String)
47+
}
48+
49+
interface TextView {
50+
var text: String
51+
var rect: Rect
52+
fun isEmpty(): Boolean
53+
}
54+
55+
class MoveableTextShape(
56+
private val textView: TextView,
57+
override val width: Int = 0,
58+
override val height: Int = 0
59+
) : TextShape {
60+
override fun move(x: Int, y: Int) {
61+
textView.rect = Rect(x, y)
62+
}
63+
64+
override fun getText(): String = textView.text
65+
66+
override fun editText(text: String) {
67+
textView.text = text
68+
}
69+
70+
override fun getBound(): Bound = with(textView.rect) {
71+
Bound(x, y, x + width, y + height)
72+
}
73+
74+
override fun toString() = getText()
75+
}
76+
77+
fun main() {
78+
val textView = object : TextView {
79+
override var text: String = "Hello"
80+
override var rect: Rect = Rect(0, 0)
81+
82+
override fun isEmpty(): Boolean = text.isEmpty()
83+
}
84+
85+
val textShape = MoveableTextShape(textView, 100, 150)
86+
87+
println(textShape.getBound().toString()) // Bound(left=0, top=0, right=100, bottom=150)
88+
89+
textShape.move(100, 100)
90+
println(textShape.getBound().toString()) // Bound(left=100, top=100, right=200, bottom=250)
91+
92+
println(textShape) // Hello
93+
94+
textShape.editText("World") // World
95+
println(textShape)
96+
}
97+
```

0 commit comments

Comments
 (0)