'κ°μ²΄μ§ν₯μ 4λ νΉμ±'μ κ°μ²΄μ§ν₯μ μ μ¬μ©νκΈ°μν 'λꡬ'μ΄λ€.
'κ°μ²΄μ§ν₯μ 5λ μμΉ'μ μ΄λ¬ν λꡬλ₯Ό μ¬λ°λ₯΄κ² μ¬μ©νλ μμΉμΌλ‘ λ³Ό μ μλ€.
κ·Έλ λ€λ©΄ λμμΈν¨ν΄μ 무μμ λΉμ ν μ μμκΉ?
'λμμΈ ν¨ν΄'μ λ μνΌμ λΉμ ν μ μλ€.
μ€μ κ°λ° νμ₯μμ λΉμ¦λμ€ μꡬ μ¬νμ μ²λ¦¬νλ©΄μ λ§λ€μ΄μ§ λ€μν ν΄κ²°μ± μ€ λ§μ μ¬λλ€μ΄ μΈμ ν 'λ² μ€νΈ νλ ν°μ€'λ₯Ό μ 리ν κ²μ΄λ€. (λμμΈ ν¨ν΄μ λΉμ°ν κ°μ²΄ μ§ν₯ νΉμ±κ³Ό μ€κ³ μμΉμ κΈ°λ°μΌλ‘ ꡬμ±)
-> μ€νλ§ μμ λ€μν λμμΈ ν¨ν΄μ νμ©νκ³ μλ€!
* μ€νλ§μ 곡μμ μ μ : "μλ° μν°νλΌμ΄μ¦ κ°λ°μ νΈνκ² ν΄μ£Όλ μ€νμμ€ κ²½λκΈ μ ν리μΌμ΄μ νλ μμν¬"
λμμΈ ν¨ν΄μ κ°μ²΄ μ§ν₯μ νΉμ± μ€ 'μμ', 'μΈν°νμ΄μ€', 'ν©μ±'μ μ΄μ©νλ€. (ν©μ±μ κ°μ²΄λ₯Ό μμ±μΌλ‘ μ¬μ©νλ κ²)
μ΄λν° ν¨ν΄ (Adapter Pattern)
ν ν΄λμ€μ μΈν°νμ΄μ€λ₯Ό ν΄λΌμ΄μΈνΈμμ μ¬μ©νκ³ μνλ λ€λ₯Έ μΈν°νμ΄μ€λ‘ λ³ννλ€.
μ΄λν°λ₯Ό μ΄μ©νλ©΄ μΈν°νμ΄μ€ νΈνμ± λ¬Έμ λλ¬Έμ κ°μ΄ μΈ μ μλ ν΄λμ€λ€μ μ°κ²°ν΄μ μΈ μ μλ€,
ODBC/JDBCκ° μ΄λν° ν¨ν΄μ μ΄μ©ν΄ λ€μν λ°μ΄ν°λ² μ΄μ€ μμ€ν μ λ¨μΌν μΈν°νμ΄μ€λ‘ μ‘°μν μ μκ² ν΄μ€λ€.
'μ΄ν리μΌμ΄μ ' - 'μ΄λν°' - 'μ€μ ꡬν체'
μ΄λν° ν¨ν΄ μ¬μ©
public class AdapterServicA {
ServiceA sa1 = new ServiceA();
void runService() {
sa1.runServiceA();
}
}
public class AdapterServicB {
ServiceB sb1 = new ServiceB();
void runService() {
sb1.runServiceB();
}
}
λ©μΈ λ©μλ
public class ClientWithAdapter {
public static void main(String[] args) {
AdapterServicA asa1 = new AdapterServicA();
AdapterServicB asb1 = new AdapterServicB();
asa1.runService();
asb1.runService();
}
}
μ΄νν°μμ λμΌν μ΄λ¦μ runService()λ₯Ό μ¬μ©ν΄μ κ°κ°μ runServiceXλ₯Ό νΈμΆνκ³ μλ€.
μ’ λ κ°μ ν΄λ³΄μλ©΄ μ΄νν°κ° νΉμ μΈν°νμ΄μ€λ₯Ό ꡬννκ² ν΄μ νλμ μΈν°νμ΄μ€μμ μμ‘΄κ΄κ³ μ£Όμ μ ν΅ν΄ λκ°μ λ©μλλ‘ κ°κ° λ€λ₯Έ
ꡬν체μ λ©μλλ₯Ό νΈμΆν μ μλ€.
"νΈμΆλΉνλ μͺ½μ λ©μλλ₯Ό νΈμΆνλ μͺ½μ μ½λμ λμνλλ‘ μ€κ°μ λ³νκΈ°λ₯Ό ν΅ν΄ νΈμΆνλ ν¨ν΄"
νλ‘μ ν¨ν΄(Proxy Pattern)
νλ‘μλ λ리μλΌλ μλ―Έμ΄λ€. λ리μλΌκ³ νλ©΄ λ€λ₯Έ λκ΅°κ°λ₯Ό λμ ν΄ κ·Έ μν μ μννλ μ‘΄μ¬λ₯Ό λ§νλ€.
νλ‘μ ν¨ν΄ μ¬μ©
- ν΄λμ€
public interface IService {
String runSomething();
}
public class Proxy implements IService {
IService service1;
public String runSomething() {
System.out.println("νΈμΆμ λν νλ¦ μ μ΄κ° μ£Όλͺ©μ , λ°ν κ²°κ³Όλ₯Ό κ·Έλλ‘ μ λ¬");
service1 = new Service();
return service1.runSomething();
}
}
public class Service implements IService {
public String runSomething() {
return "μλΉμ€ 짱!!!";
}
}
- λ©μΈ λ©μλ
public class ClientWithProxy {
public static void main(String[] args) {
// νλ‘μλ₯Ό μ΄μ©ν νΈμΆ
IService proxy = new Proxy();
System.out.println(proxy.runSomething());
}
}
μλΉμ€ κ°μ²΄κ° λ€μ΄κ° μ리μ λ리μ κ°μ²΄λ₯Ό λμ ν¬μ νλ€.
νλ‘μ ν¨ν΄μ μ€μ ν¬μΈνΈ
- λ리μ(νλ‘μ)λ μ€μ μλΉμ€μ κ°μ μ΄λ¦μ λ©μλλ₯Ό ꡬν
- λ리μλ μ€μ μλΉμ€μ λν μ°Έμ‘° λ³μλ₯Ό κ°λλ€. (ν©μ±)
- λ리μλ μ€μ μλΉμ€μ κ°μ μ΄λ¦μ κ°μ§ λ©μλλ₯Ό νΈμΆνκ³ κ·Έ κ°μ ν΄λΌμ΄μΈνΈμκ² λ°ννλ€.
- λ리μλ μ€μ μλΉμ€μ λ©μλ νΈμΆ μ νμ λ³λμ λ‘μ§μ μνν μλ μλ€.
νλ‘μ ν¨ν΄μ μ€μ μλΉμ€μ λ°νκ°μ λ³κ²½νμ§ μκ³ μ μ΄μ νλ¦μ λ³κ²½νκ±°λ λ€λ₯Έ λ‘μ§μ μννκΈ° μν΄ μ¬μ©νλ€.
λ°μ½λ μ΄ν° ν¨ν΄
μλ³Έμ μ₯μμ λνλ ν¨ν΄!
νλ‘μ ν¨ν΄κ³Ό ꡬν λ°©λ²μ΄ κ°μΌλ μ΅μ’ μ μΌλ‘ λ°ννλ λ°νκ°μ μ₯μμ λ§μ νλ€.
public class Decoreator implements IService {
IService service;
public String runSomething() {
System.out.println("νΈμΆμ λν μ₯μ μ£Όλͺ©μ , ν΄λΌμ΄μΈνΈμκ² λ°ν κ²°κ³Όμ μ₯μμ λνμ¬ μ λ¬");
service = new Service();
return "μ λ§" + service.runSomething();
}
}
λ°ν κ°μ λ€λ₯Έ κ°μ΄ μΆκ°λ κ²μ νμΈν μ μλ€.
λ°μ½λ μ΄ν° ν¨ν΄μ μ€μν¬μΈνΈλ νλ‘μ ν¨ν΄μ μ€μ ν¬μΈνΈμ 'λ°νκ°μ λ³νλ₯Ό μ€ μ μλ€'λ μ μ΄λ€.
μ±κΈν΄ ν¨ν΄ (Singleton Pattern)
μ±κΈν΄ ν¨ν΄μ΄λ μΈμ€ν΄μ€λ₯Ό νλλ§ λ§λ€μ΄ μ¬μ©νκΈ° μν ν¨ν΄
'컀λ₯μ ν', 'μ€λ λ ν', 'λλ°μ΄μ€ μ€μ κ°μ²΄' λ±κ³Ό κ°μ κ²½μ° μΈμ€ν΄μ€λ₯Ό μ¬λ¬ κ° λ§λ€κ² λλ©΄
λΆνμν μμμ μ¬μ©νκ² λκ³ , νλ‘κ·Έλ¨μ΄ μμμΉ λͺ»ν κ²°κ³Όλ₯Ό λ§λ€ μ μλ€.
μ±κΈν΄ ν¨ν΄μ μ μ©νλ©΄ λ κ°μ κ°μ²΄κ° μ‘΄μ¬ν μ μμΌλ―λ‘
1. κ°μ²΄ μμ±μ μν newμ μ μ½μ κ±Έμ΄μΌ νκ³
2. λ§λ€μ΄μ§ λ¨μΌ κ°μ²΄λ₯Ό λ°νν μ μλ λ©μλκ° νμνλ€.
- newλ₯Ό μ€νν μ μλλ‘ μμ±μμ private μ κ·Ό μ μ΄μ μ€μ
- μ μΌν λ¨μΌ κ°μ²΄λ₯Ό λ°νν μ μλ "μ μ λ©μλ" νμ
- μ μΌν λ¨μΌ κ°μ²΄λ₯Ό μ°Έμ‘°ν "μ μ μ°Έμ‘° λ³μ" νμ
μ±ν΄ν΄ ν¨ν΄ μ μ©μ μν ν΄λμ€ κ΅¬μ±
public class Singleton {
static Singleton singletonObject; // μ μ μ°Έμ‘° λ³μ
private Singleton() {
}; // private μμ±μ
// κ°μ²΄ λ°ν μ μ λ©μλ
public static Singleton getInstance() {
if (singletonObject == null) {
singletonObject = new Singleton();
}
return singletonObject;
}
}
μμ±μλ₯Ό μ¬μ©νμ§ λͺ»νλλ‘ μ€μ νκ³ "μ μ λ©μλ"λ₯Ό μ€νν΄ μ μ μ°Έμ‘° λ³μμ κ°μ²΄κ° ν λΉλμ΄ μμ§μμΌλ©΄ ν λΉν΄μ λ°ννκ³ ν λΉλμ΄ μμΌλ©΄ μ°Έμ‘° λ³μλ₯Ό λ°ννλλ‘ λ§λ€μλ€.
ν μ€νΈ μ½λ
public class Client {
public static void main(String[] args) {
// private μμ±μμμΌλ‘ new ν μ μλ€.
// Singleton s = new Singleton();
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
s1 = null;
s2 = null;
s3 = null;
}
}
μ ν μ€νΈ μ½λλ s1, s2, s3 λͺ¨λ κ°μ μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°νκ² λλ€.
4κ°μ μ°Έμ‘° λ³μκ° λͺ¨λ νλμ λ¨μΌ κ°μ²΄λ₯Ό μ°Έμ‘°νλ κ²μ νμΈν μ μλ€.'
μ±κΈν΄ ν¨ν΄μ μ€μ ν¬μΈνΈ
- private μμ±μλ₯Ό κ°λλ€.
- λ¨μΌ κ°μ²΄ μ°Έμ‘° λ³μλ₯Ό "μ μ μμ±"μΌλ‘ κ°λλ€.
- λ¨μΌ κ°μ²΄ μ°Έμ‘° λ³μκ° μ°Έμ‘°νλ "λ¨μΌ κ°μ²΄"λ₯Ό λ°ννλ getInstance() μ μ λ©μλλ₯Ό κ°λλ€.
- λ¨μΌ κ°μ²΄λ μ°κΈ° κ°λ₯ν μμ±μ κ°μ§ μλ κ²μ΄ μ μμ΄λ€. (μ½κΈ° μ μ©μ κ°λ₯)
ν νλ¦Ώ λ©μλ ν¨ν΄
μμ ν΄λμ€μ 견본 λ©μλμμ νμ ν΄λμ€κ° μ€λ²λΌμ΄λ©ν λ©μλλ₯Ό νΈμΆνλ ν¨ν΄
곡ν΅μ μΌλ‘ μ¬μ©νλ λ©μλλ μμν΄λμ€μμ ꡬν.
νμν΄λμ€λ§λ€ λ¬λΌμ§λ κ²μ μΆμν΄λμ€λ‘ ꡬν κ°μ ν.
νμν΄λμ€λ§λ€ λ¬λΌμ§ μλ μλ κ²μ μ€λ²λΌμ΄λ κ°λ₯ν ν λ©μλλ‘ λ§λ¬.
κ°μ κ³ μμ΄λ₯Ό λμμ£Όλ playWithOwnerλΌλ λ©μλκ° μμ λ νλμ μμ ν΄λμ€λ‘ μ€μ μΈμ€ν΄μ€μ λ§λ λ©μλλ‘ μ€ννκ³ μΆμ λ μ¬μ©νλ€.
Animal μΆμ ν΄λμ€
public abstract class Animal {
// ν
νλ¦Ώ λ©μλ
public void playWithOwner() {
System.out.println("κ·μΌλ₯μ΄ μ΄λ¦¬μ¨...");
play();
runSomething();
System.out.println("μνμ΄");
}
// μΆμ λ©μλ
abstract void play();
// Hook(κ°κ³ 리) λ©μλ
void runSomething() {
System.out.println("꼬리 μ΄λ μ΄λ~");
}
}
μμν΄λμ€μμ ν νλ¦Ώμ μ 곡νλ playWithOwner() ν νλ¦Ώ λ©μλλ₯Ό μ 곡νλ€.
κ·Έλ¦¬κ³ ν νλ¦Ώ λ©μλ μμ μλ play() μΆμ λ©μλμ runSomething() λ©μλκ° μλ€.
-> μΆμ λ©μλ νμ ν΄λμ€μμ ꡬν κ°μ ν¨
-> Hook λ©μλ μ€λ²λΌμ΄λ μμ
μ΄ λ ν νλ¦Ώ λ©μλμ ꡬμ±μμλ₯Ό μμ 보μ.
- ν νλ¦Ώ λ©μλ : κ³΅ν΅ λ‘μ§ μν, λ‘μ§ μν μ€ μΆμλ©μλ/ν λ©μλ νΈμΆ
- ν νλ¦Ώ λ©μλμμ νΈμΆνλ μΆμλ©μλ -> λ°λμ νμν΄λμ€κ° μ€λ²λΌμ΄λ© ν΄μΌνλ€.
- ν νλ¦Ώ λ©μλμμ νΈμΆνλ ν λ©μλ -> νμ ν΄λμ€κ° μ νμ μΌλ‘ μ€λ²λΌμ΄λ© νλ€.
ν©ν°λ¦¬ λ©μλ ν¨ν΄ (Factory Method Pattern)
μ€λ²λΌμ΄λ λ λ©μλκ° κ°μ²΄λ₯Ό λ°ννλ ν¨ν΄
ν©ν°λ¦¬ λ©μλλ κ°μ²΄λ₯Ό μμ± λ°ννλ λ©μλλ₯Ό λ§νλ€.
ν©ν°λ¦¬ λ©μλ ν¨ν΄μ νμ ν΄λμ€μμ ν©ν°λ¦¬ λ©μλλ₯Ό μ€λ²λΌμ΄λ© ν΄μ κ°μ²΄λ₯Ό λ°ννλ κ²μ μλ―Ένλ€.
μΆμ ν©ν 리 λ©μλ
public abstract class Animal {
// μΆμ ν©ν°λ¦¬ λ©μλ
abstract AnimalToy getToy();
}
μΆμ ν©ν 리 λ©μλ μ€λ²λΌμ΄λ©
public class Dog extends Animal {
// μΆμ ν©ν°λ¦¬ λ©μλ μ€λ²λΌμ΄λ©
@Override
AnimalToy getToy() {
return new DogToy();
}
}
λ©μΈ λ©μλ
public class Driver {
public static void main(String[] args) {
// ν©ν°λ¦¬ λ©μλλ₯Ό 보μ ν κ°μ²΄λ€ μμ±
Animal bolt = new Dog();
Animal kitty = new Cat();
// ν©ν°λ¦¬ λ©μλκ° λ°ννλ κ°μ²΄λ€
AnimalToy boltBall = bolt.getToy();
AnimalToy kittyTower = kitty.getToy();
// ν©ν°λ¦¬ λ©μλκ° λ°νν κ°μ²΄λ€μ μ¬μ©
boltBall.identify();
kittyTower.identify();
}
}
ν©ν°λ¦¬ λ©μλ ν¨ν΄μ..
"μ€λ²λΌμ΄λλ λ©μλκ° κ°μ²΄λ₯Ό λ°ννλ ν¨ν΄"
μ λ΅ ν¨ν΄ (Strategy Pattern)
μ λ΅ ν¨ν΄ ꡬμ±μμ 3κ°μ§
- μ λ΅ λ©μλλ₯Ό κ°μ§ μ λ΅ κ°μ²΄
- μ λ΅ κ°μ²΄λ₯Ό μ¬μ©νλ 컨ν μ€νΈ (μ λ΅ κ°μ²΄μ μ¬μ©μ/μλΉμ)
- μ λ΅ κ°μ²΄λ₯Ό μμ±ν΄ 컨ν μ€νΈμ μ£Όμ νλ ν΄λΌμ΄μΈνΈ (μ λ΅ κ°μ²΄μ 곡κΈμ)
μ λ΅ μΈν°νμ΄μ€
public interface Strategy {
public abstract void runStrategy();
}
μ λ΅ μΈν°νμ΄μ€ ꡬν
public class StrategyGun implements Strategy {
@Override
public void runStrategy() {
System.out.println("ν, νλΉ, νλ€λΉ");
}
}
public class StrategySword implements Strategy {
@Override
public void runStrategy() {
System.out.println("μ±.. μ±μμ± μ±μ±");
}
}
μ λ΅μ μ¬μ©νλ 컨ν μ€νΈ
public class Soldier {
void runContext(Strategy strategy) {
System.out.println("μ ν¬ μμ");
strategy.runStrategy();
System.out.println("μ ν¬ μ’
λ£");
}
}
μ λ΅ ν¨ν΄μ ν΄λΌμ΄μΈνΈ
public class Client {
public static void main(String[] args) {
Strategy strategy = null;
Soldier rambo = new Soldier();
// μ΄μ λ보μκ² μ λ¬ν΄μ μ ν¬λ₯Ό μννκ² νλ€.
strategy = new StrategyGun();
rambo.runContext(strategy);
System.out.println();
// κ²μ λ보μκ² μ λ¬ν΄μ μ ν¬λ₯Ό μννκ² νλ€.
strategy = new StrategySword();
rambo.runContext(strategy);
System.out.println();
// νμ λ보μκ² μ λ¬ν΄μ μ ν¬λ₯Ό μννκ² νλ€.
strategy = new StrategyBow();
rambo.runContext(strategy);
}
}
ν΄λΌμ΄μΈνΈλ μ λ΅μ λ€μνκ² λ³κ²½νλ©΄μ 컨ν μ€νΈλ₯Ό μ€νν μ μλ€.
μ λ΅ ν¨ν΄μ ν λ¬Έμ₯μΌλ‘ μμ½νλ©΄..
ν΄λΌμ΄μΈνΈκ° μ λ΅μ μμ±ν΄ μ λ΅μ μ€νν 컨ν μ€νΈμ μ£Όμ νλ ν¨ν΄
μ λ΅ ν¨ν΄μλ OCP, DIPκ° μ μ©λλ€.
ν νλ¦Ώ μ½λ°± ν¨ν΄ (Template Callback Pattern)
ν νλ¦Ώ μ½λ°± ν¨ν΄μ μ λ΅ ν¨ν΄μ λ³νμΌλ‘, μ€νλ§ 3λ νλ‘κ·Έλλ° λͺ¨λΈ μ€ νλμΈ DIμμ μ¬μ©νλ νΉλ³ν ννμ μ λ΅ ν¨ν΄μ΄λ€.
μ λ΅ν¨ν΄κ³Ό λͺ¨λ κ²μ΄ λμΌνλ° μ λ΅μ μ΅λͺ λ΄λΆ ν΄λμ€λ‘ μ μν΄μ μ¬μ©νλ€.
λ°λΌμ, μ λ΅ν¨ν΄μμ μ¬μ©νλ StrategyGun, StrategySwordλ νμκ° μλ€.
public class Client {
public static void main(String[] args) {
Soldier rambo = new Soldier();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("μ΄! μ΄μ΄μ’
μ΄ μ΄! μ΄!");
}
});
System.out.println();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("μΉΌ! μΉ΄κ°κ° μΉΌ! μΉΌ!");
}
});
System.out.println();
rambo.runContext(new Strategy() {
@Override
public void runStrategy() {
System.out.println("λλΌ! λ
λ
..λλλ
λ
λΌ!");
}
});
}
}
μ΅λͺ λ΄λΆ ν΄λμ€λ₯Ό μ¬μ©ν΄μ μ€λ²λΌμ΄λν΄μ μ¬μ©νλ κ²μ λ³Ό μ μλ€. (λ°λ‘ ν΄λμ€λ₯Ό ꡬννμ§ μκ³ μ¬μ©ν¨ [μ½λ°±])
μ μ½λλ μ€λ³΅ μ½λκ° λ°μνλ€...μ¦, 리ν©ν°λ§μ΄ κ°λ₯νλ€.
리ν©ν°λ§ ν΄λ³΄κΈ°
public class Soldier {
void runContext(String weaponSound) {
System.out.println("μ ν¬ μμ");
executeWeapon(weaponSound).runStrategy();
System.out.println("μ ν¬ μ’
λ£");
}
private Strategy executeWeapon(final String weaponSound) {
return new Strategy() {
@Override
public void runStrategy() {
System.out.println(weaponSound);
}
};
}
}
ν΄λΌμ΄μΈνΈ
public class Client {
public static void main(String[] args) {
Soldier rambo = new Soldier();
rambo.runContext("μ΄! μ΄μ΄μ’
μ΄ μ΄! μ΄!");
System.out.println();
rambo.runContext("μΉΌ! μΉ΄κ°κ° μΉΌ! μΉΌ!");
System.out.println();
rambo.runContext("λλΌ! λ
λ
..λλλ
λ
λΌ!");
}
}
μ€λ³΅λλ μ λ΅μ μμ±νλ μ½λκ° μ»¨ν μ€νΈ λ΄λΆλ‘ λ€μ΄μλ€. (μ€λ³΅λλ λΆλΆμ 컨ν μ€νΈλ‘ μ΄κ΄)
μ€νλ§μ μ΄λ° νμμΌλ‘ 리ν©ν°λ§λ ν νλ¦Ώ μ½λ°± ν¨ν΄μ DIμ μ κ·Ή νμ©νκ³ μλ€.
** μμ½ **
"μ λ΅μ μ΅λͺ λ΄λΆ ν΄λμ€λ‘ ꡬνν μ λ΅ ν¨ν΄"
OCP, DIP μ μ©λ μ€κ³ ν¨ν΄