티스토리 뷰
OCP(Open Closed Principle)는 확장에는 열려있되, 수정에는 닫혀있어야한다는 디자인 원칙이다. 게임 캐릭터에서 궁수라는 캐릭터를 예를들어 설명해보겠다.
아래 클래스는 아처(캐릭터) 클래스와 활(무기) 클래스이다.
public class Archer { private Bow bow; private int level; public Archer(int level) { bow = new Bow(); this.level = level; } public void Attack(){ StringBuilder sb = new StringBuilder(); sb.append("Archer가 데미지 "); sb.append(getPower()); sb.append("을(를) 입혔습니다."); System.out.println(sb.toString()); } public int getPower(){ return (BowPower() * CharPower()); } public int BowPower(){ return bow.getPower(); } public int CharPower(){ return (int) (level * 0.1); } }
public class Bow { private int power; public Bow() { power = 50; } public int getPower() { return power; } }
그리고 이를 사용하기 위한 메인 클래스
public class test { public static void main(String[] args) { Archer archer = new Archer(20); archer.Attack(); } }
만약 이런 코드가 있다면, 과연 이 코드는 객체지향적이라고 할 수 있을까? 만약에 아처가 칼을 든다고 하면? 아니면 석궁같은 일반적인 활과 다른 능력의 무기를 든다면 어떻게 바꾸어야할까, 결국, 아처클래스의 수정이 불가피할 것 있다. 이는 OCP에 어긋나는 일이다. 이를 해결하기 위해서는 Interface, abstract class를 사용함으로써 수정없이 사용할 수 있다.
Bow라는 클래스와 Sword를 추상화시켜 Weapon이라는 interface를 구현하면, 무기를 추가하는데, 수정없이 추가가능하도록 할 수 있다.
우선 Weapon이라는 인터페이스를 만들고 Bow는 이를 구현하도록한다.
public interface Weapon { public int getPower(); }
public class Bow implements Weapon{ // 이전과 같다. }
Archer라는 클래스에서 Bow를 Weapon으로 변경한다.
public class Archer { private Weapon weapon; private int level; public Archer(int level, Weapon weapon) { this.weapon = weapon; this.level = level; } public void Attack(){ StringBuilder sb = new StringBuilder(); sb.append("Archer가 데미지 "); sb.append(getPower()); sb.append("을(를) 입혔습니다."); System.out.println(sb.toString()); } public int getPower(){ return (WeaponPower() * CharPower()); } public int WeaponPower(){ return weapon.getPower(); } public int CharPower(){ return (int) (level * 0.1); } }
마지막으로 main()에서 레벨과 무기를 선택하고 Attack()하게 되면 이전 코드와 같은 결과값을 가지고 온다.
여기서 Sword라는 무기를 추가해보겠다.
public class Sword implements Weapon { private int power; public Sword() { power = 30; } @Override public int getPower() { return power; } }
다음 코드에서 보듯이 다른 건 변하는 것없고, Sword라는 클래스를 추가할 수 있다.
public class test { public static void main(String[] args) { Archer Bow_archer = new Archer(20, new Bow()); Archer Sword_archer = new Archer(20, new Sword()); Bow_archer.Attack(); Sword_archer.Attack(); } }
결과 값
Archer가 데미지 100을(를) 입혔습니다. Archer가 데미지 60을(를) 입혔습니다. |
** ___** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___ ** ___
Archer라는 캐릭터 말고, 워리어가 등장한다면? 이 캐릭터또한 추상화시킬 필요가 있고, 같은 방법으로 해주면 OCP를 지킬 수 있을 것같다.
'Paradigm > OOP' 카테고리의 다른 글
[OOP] Liskov Substitution Principle (0) | 2013.10.29 |
---|---|
[OOP] Single Responsibility Principle (0) | 2013.10.29 |
[OOP] 객제지향, 디자인 원리 (0) | 2013.09.27 |
[OOP] SRP 확인하기 (0) | 2013.09.27 |
[OOP] MVC패턴익히기 (0) | 2013.06.06 |
댓글
최근에 올라온 글
최근에 달린 댓글
글 보관함
- Total
- Today
- Yesterday