π μ΄λν°(Adaptor) ν¨ν΄ - μλ²½ λ§μ€ν°νκΈ°
Adaptor Pattern
μ΄λν° ν¨ν΄(Adaptor Pattern) μ΄λ μ΄λ¦ κ·Έλλ‘ ν΄λμ€λ₯Ό μ΄λν°λ‘μ μ¬μ©λλ ꡬ쑰 ν¨ν΄μ΄λ€.
μ΄λν°λ μ°λ¦¬ μ£Όλ³μλ λ§μ΄ λ³Ό μ μλ κ²μΌλ‘μ, λνμ μΌλ‘ 110V μ μ© κ°μ μ νμ 220V μ΄λν°λ₯Ό λΌμ μ¬μ©νλ κ±Έ λ€ μ μλ€. μ¦, μλ‘ νΈνμ΄ λμ§ μμ λ¨μλ₯Ό μ΄λν°λ‘ νΈνμμΌ μλμν€κ²λ νλ κ²μ΄ μ΄λν°μ μν μΈ κ²μ΄λ€.
μ΄λ₯Ό κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μ μ λͺ©ν΄λ³΄λ©΄, νΈνμ±μ΄ μλ μΈν°νμ΄μ€ λλ¬Έμ ν¨κ» λμν μ μλ ν΄λμ€λ€μ ν¨κ» μλν΄μ£Όλλ‘ λ³ν μν μ ν΄μ£Όλ νλ ν¨ν΄μ΄λΌκ³ 보면 λλ€. μλ₯Όλ€μ΄ κΈ°μ‘΄μ μλ μμ€ν μ μλ‘μ΄ μ¨λνν° λΌμ΄λΈλ¬λ¦¬λ₯Ό μΆκ°νκ³ μΆκ±°λ, Legacy μΈν°νμ΄μ€λ₯Ό μλ‘μ΄ μΈν°νμ΄μ€λ‘ κ΅μ²΄νλ κ²½μ°μ μ΄λν° ν¨ν΄μ μ¬μ©νλ©΄ μ½λμ μ¬μ¬μ©μ±μ λμΌ μ μλ€.
μ¦, μ΄λν°λ μ΄λ―Έ ꡬμΆλμ΄ μλ κ²μ μλ‘μ΄ μ΄λ€κ²μ μ¬μ©ν λ μ μͺ½ κ°μ νΈνμ±μ μ μ§ν΄ μ£ΌκΈ° μν΄ μ¬μ©νλ κ²μΌλ‘μ, κΈ°μ‘΄ μμ€ν μμ μλ‘μ΄ μ 체μμ μ 곡νλ κΈ°λ₯μ μ¬μ©νλ €κ³ ν λ μλ‘ κ°μ μΈν°νμ΄μ€λ₯Ό μ΄λν°λ‘ μΌμΉμμΌμ€μΌλ‘μ¨ νΈνμ± λ° μ κ· κΈ°λ₯ νμ₯μ ν μ μλ€κ³ 보면 λλ€.
μ΄λν°κ° Legacy μΈν°νμ΄μ€λ₯Ό κ°μΈμ μλ‘μ΄ μΈν°νμ΄μ€λ‘ λ³ννκΈ° λλ¬Έμ Wrapper ν¨ν΄μ΄λΌκ³ λ λΆλ¦¬μ΄λ€.
μ΄λν° ν¨ν΄ ꡬ쑰
Adapter ν¨ν΄μλ κΈ°μ‘΄ μμ€ν μ ν΄λμ€λ₯Ό μμ(Inheritance) ν΄μ νΈν μμ μ ν΄μ£Όλ, ν©μ±(Composition) ν΄μ νΈν μμ μ ν΄μ£Όλμ λ°λΌ, λ κ°μ§ ν¨ν΄ λ°©λ²μΌλ‘ λλκ² λλ€.
κ°μ²΄ μ΄λν° (Object Adaptor)
- ν©μ±(Composition)λ 맴λ²μκ² μμμ μ΄μ©ν μ΄λν° ν¨ν΄ (μΆμ² π)
- μκΈ°κ° ν΄μΌ ν μΌμ ν΄λμ€ λ§΄λ² κ°μ²΄μ λ©μλμκ² λ€μ μν΄μΌλ‘μ¨ λͺ©μ μ λ¬μ±νλ κ²μ μμμ΄λΌκ³ νλ€.
- ν©μ±μ νμ©νκΈ° λλ¬Έμ λ°νμ μ€μ Adaptee(Service)κ° κ²°μ λμ΄ μ μ°νλ€.
- κ·Έλ¬λ Adaptee(Service) κ°μ²΄λ₯Ό νλ λ³μλ‘ μ μ₯ν΄μΌ λκΈ° λλ¬Έμ κ³΅κ° μ°¨μ§ λΉμ©μ΄ λ λ€.
- Adaptee(Service) : μ΄λν° λμ κ°μ²΄. κΈ°μ‘΄ μμ€ν / μΈλΆ μμ€ν / μ¨λνν° λΌμ΄λΈλ¬λ¦¬
- Target(Client Interface) : Adapter κ° κ΅¬ννλ μΈν°νμ΄μ€.
- Adapter : Client μ Adaptee(Service) μ€κ°μμ νΈνμ±μ΄ μλ λμ μ°κ²°μμΌμ£Όλ μν μ λ΄λΉ.
- Object Adaptor λ°©μμμ ν©μ±μ μ΄μ©ν΄ ꡬμ±νλ€.
- Adaptee(Service)λ₯Ό λ°λ‘ ν΄λμ€ λ©€λ²λ‘ μ€μ νκ³ μμμ ν΅ν΄ λμμ 맀μΉμν¨λ€.
- Client : κΈ°μ‘΄ μμ€ν μ μ΄λν°λ₯Ό ν΅ν΄ μ΄μ©νλ €λ μͺ½. Client Interfaceλ₯Ό ν΅νμ¬ Serviceλ₯Ό μ΄μ©ν μ μκ² λλ€.
// Adaptee : ν΄λΌμ΄μΈνΈμμ μ¬μ©νκ³ μΆμ κΈ°μ‘΄μ μλΉμ€ (νμ§λ§ νΈνμ΄ μλμ λ°λ‘ μ¬μ© λΆκ°λ₯)
class Service {
void specificMethod(int specialData) {
System.out.println("κΈ°μ‘΄ μλΉμ€ κΈ°λ₯ νΈμΆ + " + specialData);
}
}
// Client Interface : ν΄λΌμ΄μΈνΈκ° μ κ·Όν΄μ μ¬μ©ν κ³ μμ€μ μ΄λν° λͺ¨λ
interface Target {
void method(int data);
}
// Adapter : Adaptee μλΉμ€λ₯Ό ν΄λΌμ΄μΈνΈμμ μ¬μ©νκ² ν μ μλλ‘ νΈν μ²λ¦¬ ν΄μ£Όλ μ΄λν°
class Adapter implements Target {
Service adaptee; // compositionμΌλ‘ Service κ°μ²΄λ₯Ό ν΄λμ€ νλλ‘
// μ΄λν°κ° μΈμ€ν΄μ€νλλ©΄ νΈνμν¬ κΈ°μ‘΄ μλΉμ€λ₯Ό μ€μ
Adapter(Service adaptee) {
this.adaptee = adaptee;
}
// μ΄λν°μ λ©μλκ° νΈμΆλλ©΄, Adapteeμ λ©μλλ₯Ό νΈμΆνλλ‘
public void method(int data) {
adaptee.specificMethod(data); // μμ
}
}
class Client {
public static void main(String[] args) {
// 1. μ΄λν° μμ± (κΈ°μ‘΄ μλΉμ€λ₯Ό μΈμλ‘ λ°μ νΈν μμ
μ²λ¦¬)
Target adapter = new Adapter(new Service());
// 2. Client Interfacμ μ€νμ λ°λΌ λ©μλλ₯Ό μ€ννλ©΄ κΈ°μ‘΄ μλΉμ€μ λ©μλκ° μ€νλλ€.
adapter.method(1);
}
}
ν΄λμ€ μ΄λν° (Class Adaptor)
- ν΄λμ€ μμμ μ΄μ©ν μ΄λν° ν¨ν΄
- Adaptee(Service)λ₯Ό μμνκΈ° λλ¬Έμ λ°λ‘ κ°μ²΄ ꡬνμμ΄ λ°λ‘ μ½λ μ¬μ¬μ©μ΄ κ°λ₯νλ€.
- μμμ λνμ μΌλ‘ κΈ°μ‘΄μ ꡬνλ μ½λλ₯Ό μ¬μ¬μ©νλ λ°©μμ΄μ§λ§, μλ°μμλ λ€μ€ μμ λΆκ° λ¬Έμ λλ¬Έμ μ λ°μ μΌλ‘ κΆμ₯νμ§λ μλ λ°©λ²μ΄λ€.
- Adaptee(Service) : μ΄λν° λμ κ°μ²΄. κΈ°μ‘΄ μμ€ν / μΈλΆ μμ€ν / μ¨λνν° λΌμ΄λΈλ¬λ¦¬
- Target(Cient Interface) : Adapter κ° κ΅¬ννλ μΈν°νμ΄μ€.
- Adapter : Client μ Adaptee(Service) μ€κ°μμ νΈνμ±μ΄ μλ λμ μ°κ²°μμΌμ£Όλ μν μ λ΄λΉ.
- Class Adaptor λ°©μμμ μμμ μ΄μ©ν΄ ꡬμ±νλ€.
- Existing Classμ Adaptee(Service) λ₯Ό λμμ implements, extends νμ¬ κ΅¬ννλ€.
- Client : κΈ°μ‘΄ μμ€ν μ μ΄λν°λ₯Ό ν΅ν΄ μ΄μ©νλ €λ μͺ½. Client Interfaceλ₯Ό ν΅νμ¬ Serviceλ₯Ό μ΄μ©ν μ μκ² λλ€.
// Adaptee : ν΄λΌμ΄μΈνΈμμ μ¬μ©νκ³ μΆμ κΈ°μ‘΄μ μλΉμ€ (νμ§λ§ νΈνμ΄ μλμ λ°λ‘ μ¬μ© λΆκ°λ₯)
class Service {
void specificMethod(int specialData) {
System.out.println("κΈ°μ‘΄ μλΉμ€ κΈ°λ₯ νΈμΆ + " + specialData);
}
}
// Client Interface : ν΄λΌμ΄μΈνΈκ° μ κ·Όν΄μ μ¬μ©ν κ³ μμ€μ μ΄λν° λͺ¨λ
interface Target {
void method(int data);
}
// Adapter : Adaptee μλΉμ€λ₯Ό ν΄λΌμ΄μΈνΈμμ μ¬μ©νκ² ν μ μλλ‘ νΈν μ²λ¦¬ ν΄μ£Όλ μ΄λν°
class Adapter extends Service implements Target {
// μ΄λν°μ λ©μλκ° νΈμΆλλ©΄, λΆλͺ¨ ν΄λμ€ Adapteeμ λ©μλλ₯Ό νΈμΆ
public void method(int data) {
specificMethod(data);
}
}
class Client {
public static void main(String[] args) {
// 1. μ΄λν° μμ±
Target adapter = new Adapter();
// 2. μΈν°νμ΄μ€μ μ€νμ λ°λΌ λ©μλλ₯Ό μ€ννλ©΄ κΈ°μ‘΄ μλΉμ€μ λ©μλκ° μ€νλλ€.
adapter.method(1);
}
}
μ΄λν° ν¨ν΄ νΉμ§
ν¨ν΄ μ¬μ© μκΈ°
- λ κ±°μ μ½λλ₯Ό μ¬μ©νκ³ μΆμ§λ§ μλ‘μ΄ μΈν°νμ΄μ€κ° λ κ±°μ μ½λμ νΈνλμ§ μμ λ
- μ΄λ―Έ λ§λ κ²μ μ¬μ¬μ©νκ³ μ νλ μ΄ μ¬μ¬μ© κ°λ₯ν λΌμ΄λΈλ¬λ¦¬λ₯Ό μμ ν μ μμ λ
- μ΄λ―Έ λ§λ€μ΄μ§ ν΄λμ€λ₯Ό μλ‘μ΄ μΈν°νμ΄μ€(API)μ λ§κ² κ°μ‘°ν λ
- μννΈμ¨μ΄μ ꡬ λ²μ κ³Ό μ λ²μ μ 곡쑴μν€κ³ μΆμλ
κΈ°μ‘΄μ ν΄λμ€λ₯Ό μλ‘μ΄ μΈν°νμ΄μ€μ λ§κ² κ°μ‘°νκ³ μΆμλ, μ°λ¦¬λ κΈ°μ‘΄ ν΄λμ€μ μμ€λ₯Ό λ°κΎΈμ΄ μμ μ ν΄μμλ€. νμ§λ§ μ΄λ°μμΌλ‘ νλ‘κ·Έλ¨μ μ΄μ©νλ©΄ μ΄λ―Έ λμ ν μ€νΈκ° λλ κΈ°μ‘΄μ ν΄λμ€λ₯Ό λ€μ νλ² ν μ€νΈ ν΄μΌ νλ€. λ§μΌ ν΄λμ€ μμ€κ° λͺμ²μ€μ΄λΌλ©΄ μ΄μ©νκΈ° κ½€λ νλ€ κ²μ΄λ€.
μ΄λ¬ν κ΄μ μμ μ΄λν°(Adapter) ν¨ν΄μ κΈ°μ‘΄μ ν΄λμ€λ₯Ό μμ νμ§ μκ³ μλ‘μ΄ μΈν°νμ΄μ€μ λ§κ² νΈνμμ μ μ€κ³νμ¬ ν΄μ£Όλ κ²μ΄λ€.
ν¨ν΄ μ₯μ
- νλ‘κ·Έλ¨μ κΈ°λ³Έ λΉμ¦λμ€ λ‘μ§μμ μΈν°νμ΄μ€ λλ λ°μ΄ν° λ³ν μ½λλ₯Ό λΆλ¦¬ν μ μκΈ° λλ¬Έμ λ¨μΌ μ± μ μμΉ(SRP)μ λ§μ‘±νλ€.
- κΈ°μ‘΄ ν΄λμ€ μ½λλ₯Ό 건λ€μ§ μκ³ ν΄λΌμ΄μΈνΈ μΈν°νμ΄μ€λ₯Ό ν΅ν΄ μ΄λν°μ μλνκΈ° λλ¬Έμ κ°λ°© νμ μμΉ(OCP)μ λ§μ‘±νλ€.
- λ§μΌ μΆκ°λ‘ νμν λ©μλκ° μλ€λ©΄ μ΄λν°μ λΉ λ₯΄κ² λ§λ€ μ μλ€. λ§μ½ λ²κ·Έκ° λ°μν΄λ κΈ°μ‘΄μ ν΄λμ€μλ λ²κ·Έκ° μμΌλ―λ‘ Adapter μν μ ν΄λμ€λ₯Ό μ€μ μ μΌλ‘ μ‘°μ¬νλ©΄ λκ³ , νλ‘κ·Έλ¨ κ²μ¬λ μ¬μμ§λ€.
ν¨ν΄ λ¨μ
- μλ‘μ΄ μΈν°νμ΄μ€μ μ΄λν° ν΄λμ€ μΈνΈλ₯Ό λμ ν΄μΌ νκΈ° λλ¬Έμ μ½λμ 볡μ‘μ±μ΄ μ¦κ°νλ€.
- λλ‘λ μ§μ μλΉμ€(Adaptee) ν΄λμ€λ₯Ό λ³κ²½νλκ²μ΄ κ°λ¨ν μ μλ κ²½μ°κ° μκΈ° λλ¬Έμ μ μ€ν μ ννμ¬μΌ νλ€.
μμ λ₯Ό ν΅ν΄ μμ보λ Adaptor ν¨ν΄
νλ‘κ·Έλ¨μ μμ§μ κ΅μ²΄νκ³ νΈνμν€κΈ°
μ°λ¦¬ νμ¬μμλ A νμ¬μμ κ°λ°ν Sortμμ§ μ루μ μ ꡬ맀ν΄μ μ°λ¦¬ νμ¬μ Sortλ¨Έμ μ νμ¬νμ¬ μ¬μ©νκ³ μμ΄μκ³ νλ€.
interface ISortEngine {
void setList(); // μ λ ¬ν 리μ€νΈ
void sort(); // μ λ ¬ μκ³ λ¦¬μ¦
void reverseSort(); // μμ μ λ ¬ μκ³ λ¦¬μ¦
void printSortListPretty(); // μ λ ¬λ 리μ€νΈλ₯Ό μμκ² μΆλ ₯
}
class A_SortEngine implements ISortEngine {
public void setList() {}
public void sort() {}
public void reverseSort() {}
public void printSortListPretty() {}
}
// Client μν μ νλ ν΄λμ€ : Sort μμ§ κ°μ²΄λ₯Ό λ°μ μ€ν
class SortingMachine {
ISortEngine engine;
void setEngine(ISortEngine engine) { this.engine = engine; }
void sortingRun() {
engine.setList();
engine.sort();
engine.printSortListPretty();
engine.reverseSort();
engine.printSortListPretty();
}
public static void main(String[] args) {
SortingMachine machine = new SortingMachine();
machine.setEngine(new A_SortEngine());
machine.sortingRun();
}
}
κ·Έλ°λ° A νμ¬μ Sortμμ§ μ±λ₯μ΄ μ κ·Έλμ νμν κ²°κ³Ό μ±λ₯μ΄ μ’μ B νμ¬μ Sortμμ§μΌλ‘ κ΅μ²΄νκΈ°λ‘ κ²°μ νλ€. κ·Έλμ B νμ¬λ‘λΆν° μμ§ λͺ μΈμλ₯Ό λ°μμλλ, κ·Έλ°λ° λ€μκ³Ό κ°μ΄ κΈ°μ‘΄ Sortμμ§κ³Όλ λμ λ©μλ μκ·Έλμ²κ° λ¬λμΌλ©° μ¬μ§μ΄ μ§μνμ§ μλ λ©μλ(printSortListPretty)λ μ‘΄μ¬νλ€.
class B_SortEngine {
public void setList() {} // μ λ ¬ν 리μ€νΈ
public void sorting(boolean isReverse) {} // μ λ ¬ / μμ μ λ ¬ μκ³ λ¦¬μ¦ (νλΌλ―Έν°λ‘ μμ κ²°μ )
}
μ°λ¦¬ νμ¬μ Sortμμ§μμ μΈν°νμ΄μ€λ₯Ό λμ΄λ€ μ°κ³ μμκΈ° λλ¬Έμ B_Sort μμ§μ μΈν°νμ΄μ€λ₯Ό implements ν΄λ νΈνμ΄ λμ§ μμ ν¬λν° μμ μμ μ΄ νμλΆκ°κ²° νλ©°, νΉν printSortListPretty λ©μλ λΆμ¬λ μ‘°κΈ μΉλͺ μ μ΄μλλ° μλνλ©΄ μ΄ λ©μλλ κ΅μ₯ν μ΄μκ² μ λ ¬λ 리μ€νΈλ₯Ό μΆλ ₯ν΄μ λ§μμ λ€μκΈ° λλ¬Έμ΄λ€. νμ§λ§ B νμ¬μ μμ§ μ±λ₯μ΄ A νμ¬ λ³΄λ€ 4λ°°λ λΉ¨λκΈ° λλ¬Έμ λΉμ©μ΄ λ€μ΄λ μ΄λ»κ²λ κ΅μ²΄ν΄μΌ νλ μν©μ΄λ€.
νΈνμ±μ λ¬Έμ κ° μλ μ½λ β
μΌλ¨ κ°μ₯ μ§κ΄μ μΈ ν΄κ²°λ²μ SortingMachine ν΄λμ€λ₯Ό ν΅μ§ μμ ν΄μ μ μνλ λ°©λ²μ΄λ€. κ·Έλμ 머리λ₯Ό μ₯μ΄μ§ κ²°κ³Ό κΈ°μ‘΄ μ¬μ©νλ μΈν°νμ΄μ€ λ΄λΆλ₯Ό μμ νμ¬ λ§μ»€ μΈν°νμ΄μ€ μ©λλ‘λ§ μ΄μ©νκ³ , Sortλ¨Έμ μμ λ€μ΄ μΊμ€ν μΌλ‘ ν΅ν΄ λμ΄ νΈνμ μμΌ μ£Όμλ€.
interface ISortEngine {
// λ μμ§ κ°μ κ°κ·Ήμ΄ λ§μ§ μκΈ° λλ¬Έμ μ΄μ©μμμ΄ μμ ν΄λ²λ¦¬κ³ , λ§μ»€ μΈν°νμ΄μ€ μ©λλ‘λ§ μ¬μ©
}
class A_SortEngine implements ISortEngine {
public void setList() {}
public void sort() {}
public void reverseSort() {}
public void printSortListPretty() {}
}
class B_SortEngine implements ISortEngine {
public void setList() {} // μ λ ¬ν 리μ€νΈ
public void sorting(boolean isReverse) {} // μ λ ¬ / μμ μ λ ¬ μκ³ λ¦¬μ¦ (νλΌλ―Έν°λ‘ μμ κ²°μ )
}
// Client μν μ νλ ν΄λμ€ : Sort μμ§ κ°μ²΄λ₯Ό λ°μ μ€ν
class SortingMachine {
// ISortEngine engine; - νμ μμ΄μ Έμ deprecated
// void setEngine(ISortEngine engine) { this.engine = engine; } - νμ μμ΄μ Έμ deprecated
void sortingRun() {
A_SortEngine Aengine = (A_SortEngine) this.engine;
B_SortEngine Bengine = (B_SortEngine) this.engine;
Bengine.setList();
Bengine.sorting(false);
Aengine.setList();
Aengine.printSortListPretty();
}
public static void main(String[] args) {
SortingMachine machine = new SortingMachine();
// machine.setEngine(new A_SortEngine());
machine.sortingRun();
}
}
μ΄ μ½λλ₯Ό λ μ΄μ μ μ§ λ³΄μ ν κ²μ΄ μλλΌλ©΄ μ΄λλ‘ μ μ©νλ©΄ λλ€. νμ§λ§ κ°μ²΄ μ§ν₯ νλ‘κ·Έλλ°μμ κ³ μμ€μ΄ μλ μ μμ€ λͺ¨λλ‘ μμ‘΄ν΄μ λ‘μ§μ μ§λ건 μ’μ§μμΌλ©°, λ§μΌ λμ€μ λ€λ₯Έ νμ¬μ μμ§μΌλ‘ λ κ΅μ²΄ν΄μΌν κ²½μ°κ° μ¨λ€λ©΄ μκ·Έλλ μ΅μ§λ‘ νΈνμν€λλΌ λ―μ΄κ³ μΉ μ½λ λ€μ μ 체λ₯Ό λ―μ΄κ³ μ³μΌ λ μ§λ λͺ¨λ₯Έλ€. λ°λΌμ μ΄λ¬ν λ Έκ°λ€ μ€λ¬μ΄ λ°©λ²μ μ’μ§μλ€.
κ°μ²΄ μ΄λν° ν¨ν΄μ μ μ©ν μ½λ βοΈ
μ΄λν° ν¨ν΄μ ν΄λΌμ΄μΈνΈκ° μ¬μ©νλ μΈν°νμ΄μ€λ μ ν΄μ Έ μλλ°, μ μ©ν μ½λ(Adaptee)κ° ν΄λΉ μΈν°νμ΄μ€λ₯Ό λ°λ₯΄μ§ μμλ ν΄λΌμ΄μΈνΈμ Adaptee μ¬μ΄μ κ°κ·Ήμ μ΄λν°λ‘ 맀κΏμ Adapteeλ₯Ό μ¬μ¬μ©ν μ μλλ‘ νλ€.
λ°λΌμ μ°λ¦¬ νμ¬μ Sortμμ§μμ μ΄μ©νλ μΈν°νμ΄μ€λ₯Ό μλμ§ μκ³ λ³λμ μ΄λν° SortengineAdaptor ν΄λμ€λ₯Ό λ§λ€μ΄μ νΈν μμ μ μμΌμ€ κ²μ΄λ€.
// κΈ°μ‘΄μ μΈν°νμ΄μ€λ μλμ§ μλλ€
interface ISortEngine {
void setList(); // μ λ ¬ν 리μ€νΈ
void sort(); // μ λ ¬ μκ³ λ¦¬μ¦
void reverseSort(); // μμ μ λ ¬ μκ³ λ¦¬μ¦
void printSortListPretty(); // μ λ ¬λ 리μ€νΈλ₯Ό μμκ² μΆλ ₯
}
class A_SortEngine implements ISortEngine {
public void setList() {}
public void sort() {}
public void reverseSort() {}
public void printSortListPretty() {}
}
class B_SortEngine {
public void setList() {} // μ λ ¬ν 리μ€νΈ
public void sorting(boolean isReverse) {} // μ λ ¬ / μμ μ λ ¬ μκ³ λ¦¬μ¦ (νλΌλ―Έν°λ‘ μμ κ²°μ )
}
// κ°μ²΄ μ΄λν°λ₯Ό ꡬμ±νλ€.
class SortEngineAdaptor implements ISortEngine {
// (λ μμ§μ composition νμ¬ μ΄μ©)
A_SortEngine Aengine;
B_SortEngine Bengine;
SortEngineAdaptor(A_SortEngine Aengine, B_SortEngine Bengine) {
this.Aengine = Aengine;
this.Bengine = Bengine;
}
@Override
public void setList() {
Bengine.setList();
}
@Override
public void sort() {
Bengine.sorting(false); // λ©μλ μκ·Έλμ²κ° λ¬λΌκ³ μμμ ν΅ν΄ νΈν μμ
}
@Override
public void reverseSort() {
Bengine.sorting(true); // λ©μλ μκ·Έλμ²κ° λ¬λΌκ³ μμμ ν΅ν΄ νΈν μμ
}
@Override
public void printSortListPretty() {
Aengine.printSortListPretty(); // B μμ§μ μλ κΈ°λ₯μ A μμ§μΌλ‘ μ€ν
}
}
// Client μν μ νλ ν΄λμ€ : Sort μμ§ κ°μ²΄λ₯Ό λ°μ μ€ν
class SortingMachine {
ISortEngine engine;
void setEngine(ISortEngine engine) { this.engine = engine; }
void sortingRun() {
engine.setList();
engine.sort();
engine.printSortListPretty();
engine.reverseSort();
engine.printSortListPretty();
}
public static void main(String[] args) {
// ν΄λΌμ΄μΈνΈμ λ¨Έμ μ μλ³Έ μμ§ λμ μ΄λν°λ₯Ό ν λΉνλ€.
ISortEngine adaptor = new SortEngineAdaptor(new A_SortEngine(), new B_SortEngine());
SortingMachine machine = new SortingMachine();
machine.setEngine(adaptor);
machine.sortingRun();
}
}
κΈ°μ‘΄ ν΄λΌμ΄μΈνΈ μ½λλ 건λ€μ§ μμμ±, κ°μ²΄ ν λΉλ§ μ΄λν° κ°μ²΄λ₯Ό λ£μΌλ©΄ μμ μμ΄ B μμ§ μ΄μ©μ΄ κ°λ₯ν΄μ§λκ±Έ λ³Ό μ μλ€. λμ€μ C μμ§, D μμ§μΌλ‘ κ΅μ²΄νλ€κ³ νλλΌλ μ΄λν° ν΄λμ€λ§ μ μ ν μλ§ λ΄μ£Όλ©΄ λκΈ° λλ¬Έμ μ μ§λ³΄μκ° μ©μ΄ν΄μ§λ€.
μ΄ μμ μμ κΈ°μ‘΄μ μΈν°νμ΄μ€λ₯Ό μ¬νμ© νλ€λ 컨μ μΌλ‘ μ κ·Όν΄μ μ΄λν°λ₯Ό ꡬμ±νμλ€. νμ§λ§ λ§μΌ μλ‘μ΄ λ€λ₯Έ μΈν°νμ΄μ€ λͺ μΈκ° νμνλ€λ©΄, μ μΈν°νμ΄μ€λ₯Ό λ§λ€κ³ μ΄λν°λ‘ μμμ ν΅ν΄ νΈνμμ μ ν΄μ£Όλ©΄ λκΈ° λλ¬Έμ μ΄λ€μμΌλ‘ μ κ·Όνλ μκ΄ μλ€.
ν΄λμ€ μ΄λν° ν¨ν΄μ μ μ©ν μ½λ β
μ΄λ²μ ν΄λμ€ μ΄λν° νμμΌλ‘ ꡬμ±ν΄λ³΄λ©΄ λ€μκ³Ό κ°μ΄ λλ€. μμ ꡬ쑰λ₯Ό ν΅ν΄ νμ€ν μ¬ννκ² λ³΄μΌμλ μμ§λ§ μλ°μμλ λ¨μΌ μμλ§ κ°λ₯νκΈ° λλ¬Έμ λ§μΌ μ¬λ¬κ°μ Adapteeλ₯Ό νΈνμμ μ ν΄μ€μΌ νλ€λ©΄ νκ³μ μ΄ μ‘΄μ¬νλ€.
// ν΄λμ€ μ΄λν°λ₯Ό ꡬμ±νλ€.
class SortEngineAdaptor extends B_SortEngine implements ISortEngine {
@Override
public void setList() {
super.setList();
}
@Override
public void sort() {
sorting(false);
}
@Override
public void reverseSort() {
sorting(true);
}
@Override
public void printSortListPretty() {
// A_SortEngine ν΄λμ€μ μλ³Έ printSortListPretty λ©μλμ μκ³ λ¦¬μ¦ λ‘μ§μ κ·Έλλ‘ λ³΅λΆ λ° κ΅¬ν
}
}
// Client μν μ νλ ν΄λμ€ : Sort μμ§ κ°μ²΄λ₯Ό λ°μ μ€ν
class SortingMachine {
ISortEngine engine;
void setEngine(ISortEngine engine) { this.engine = engine; }
void sortingRun() {
engine.setList();
engine.sort();
engine.printSortListPretty();
engine.reverseSort();
engine.printSortListPretty();
}
public static void main(String[] args) {
// ν΄λΌμ΄μΈνΈμ λ¨Έμ μ μλ³Έ μμ§ λμ μ΄λν°λ₯Ό ν λΉνλ€.
ISortEngine adaptor = new SortEngineAdaptor();
SortingMachine machine = new SortingMachine();
machine.setEngine(adaptor);
machine.sortingRun();
}
}
μ€λ¬΄μμ μ°Ύμ보λ Adaptor ν¨ν΄
Java
- java.util.Arrays μ asList()
- java.util.Collections μ list()
- java.util.Collections μ enumeration()
- java.io.InputStreamReader(InputStream) (returns a Reader)
- java.io.OutputStreamWriter(OutputStream) (returns a Writer)
- javax.xml.bind.annotation.adapters.XmlAdapter μ marshal() and unmarshal()
InputStreamReader
μ½μμμ μ λ ₯μ λ°κ³ μΆμλ Scanner ν΄λμ€μ κ°μ₯ λ§μ΄ μ¬μ©νλ κ²μ΄ BufferedReader μΈλ°, μλμ κ°μ΄ μμ±μ μΈμλ‘ InpuStreamReader κ°μ²΄λ₯Ό λ£μ΄ μ¬μ©νλ κ²μ λ³Έ μ μ΄ μμ κ²μ΄λ€.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
μ΄ μ½λμ ν΅μ¬μ inputμ ννλ System.in μ BufferedReader κ°μ²΄μ μ¬μ©νκ³ μΆμλ° μ΄ μ€κ°μ InpuStreamReader κ° μ΄λν° μν μ νκ³ μλ κ²μ΄λ€.
λ¨Όμ BufferedReader ν΄λμ€λ₯Ό μ΄ν΄λ³΄λ©΄ μμ±μμ μλμ κ°μ΄ Reader νμ μ λ°λκ±Έ λ³Ό μ μλ€.
νμ§λ§ System ν΄λμ€μ in νλλ₯Ό 보면 InputStream νμ
μΌλ‘ ꡬμ±λμ΄ μλ€. μ¦, μλ‘ νμ
μ΄ λ§μ§ μμ BufferedReader(System.in) κ³Ό κ°μ΄ μ¬μ©ν μ μλ κ²μ΄λ€.
κ·Έλμ μ΄ λμ μ°κ²°μμΌ μ£Όλ μ΄λν°κ° InputStreamReader ν΄λμ€μ΄λ€.
InputStreamReader ν΄λμ€λ μμ±μλ‘ InputStream νμ μ λ°κ³ μΈμ€ν΄μ€ν νλ©°, InputStreamReader ν΄λμ€ μμ²΄κ° Reader μΆμ ν΄λμ€λ₯Ό μμνκ³ μκΈ° λλ¬Έμ μ μΊμ€ν μΌλ‘ λ³ννμ¬ BufferedReaderμ μμ±μ μΈμλ‘ λ€μ΄κ°κ² ν΄μ£Όλ κ²μ΄λ€.
μ΄ κ΅¬μ‘°λ₯Ό UML λ‘ λ³΄λ©΄ μλμ κ°κ² λλ€. BufferedReader ν΄λμ€μ InputStreamReader ν΄λμ€λ Reader μΆμ ν΄λμ€λ₯Ό λμμ μμλ°κ³ μλ€.
InputStreamReader ν΄λμ€λ InputStream νμ μ λ°μ μ μλ μμ±μλ₯Ό κ°μ§κ³ μμΌλ―λ‘, System.in μ InputStreamReader μμ±μμ λ겨 μΈμ€ν΄μ€ν νλ©΄, κ°μ Reader λΆλͺ¨ ν΄λμ€λ₯Ό μμνκ³ μλ BufferedReaderμ μμ±μμ μΈμλ‘ λ겨μ€μ μκΈ° λλ¬Έμ, λ§μΉ System.in μ BufferedReaderμ λ£μ κ²μ²λΌ νΈν μν μ InputStreamReader κ° μ΄λν°λ‘μ ννκ³ μλ€κ³ λ³Ό μ μλ€.
λ°λΌμ μ 리νλ©΄ InputStreamReader ν΄λμ€λ₯Ό Adapter, System.in μ Adaptee, Reader λ₯Ό Target Interface λΌκ³ ν μ μλ€.
Arraysμ asList()
κΈ°μ‘΄μ λ°°μ΄(Array)μ 리μ€νΈ(List)λ‘ λ³ν & νΈν μμ
μ ν΄μ£Όλ Arrays.asList() λ μ΄μ°λ³΄λ©΄ μ΄λν°λΌκ³ λ³Ό μ μλ€.
public static void main(String[] args) {
// String λ°°μ΄ : adaptee κΈ°μ‘΄ μλΉμ€
String[] s = {"a", "b", "c"};
// List<String> : target μΈν°νμ΄μ€
List<String> list
// Arrays.asList() : adapter κΈ°μ‘΄ μλΉμ€ λ°°μ΄μ 리μ€νΈλ‘ λ³ν & νΈννκ² ν΄μ£Όλ μν
list = Arrays.asList(s);
}
Collectionsμ enumeration()
μμλ 리μ€νΈμ Enumeration κ°μ λ³ν & νΈν μμ μ ν΄μ£Όλ Collections μ μ μ λ©μλλ μ΄λν°λΌκ³ λ³Ό μ μλ€.
public static void main(String[] args) {
// 리μ€νΈ : adaptee κΈ°μ‘΄ μλΉμ€
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// Enumeration<String> : target μΈν°νμ΄μ€
Enumeration<String> enum
// adapter κΈ°μ‘΄ μλΉμ€ λ°°μ΄μ 리μ€νΈλ‘ λ³ν & νΈννκ² ν΄μ£Όλ μν
enum = Collections.enermeration(list); // list → enermeration
ArrayList<String list2 = Collections.list(enum) // enermeration → list
}
# μ°Έκ³ μλ£
μ½λ©μΌλ‘ νμ΅νλ GoFμ λμμΈ ν¨ν΄ - λ°±κΈ°μ
https://refactoring.guru/design-patterns/adapter
https://yaboong.github.io/design-pattern/2018/10/15/adapter-pattern/