Written by JS970
on
on
소프트웨어시스템설계 2023-04-03 수업정리
Flow
- Interface vs Abstract Class
- RobotStrategy Review
- Observer Pattern
Interfacs vs Abstract Class
- java에서는 C++과 달리 abstract method가 없어도 Abstract Class로 선언이 가능하다.
- 이렇게 선언할 결우 인스턴스 추상 메소드는 없지만 인스턴스 생성은 불가능한 추상 클래스가 된다.
- Concrete Class에서 조금이라도 중복되는 동작이 있다면 Abstract Class를 사용해서 코드 중복을 피할 수 있다.
- 하지만 유지보수 관점에서 보수적으로 접근했을 경우, 새로운 클래스의 선언이 이루어졌을 때, 이전의 클래스들과 공통되는 부분이 없다면 올바른 상속이 불가능하다는 문제가 발생할 수 있다. 따라서 Strategy Pattern의 적용에 있어서는 Abstract Class보다는 Interface가 더 적합하다고 볼 수 있다.
- 하지만 당연히 Abstract Class로 구현했을 때의 장점 또한 존재하므로(code duplication이 없음) 따로 정답이 정해져 있다기 보다는 상황에 따라 적절하게 선택하는 것이 바람직하다.
RobotStrategy Review
- 위 UML에서 MoveOptionList, AttackOptionList는 굳이 필요 없는 class이다.
- requirement수준에서 비슷한 레벨의 사항들을 class로 구현하는데, 위 UML에서 해당 클래스들은 Robot, Attack, Move 와 같은 레벨이라고 볼 수 없다.
- 또한, List를 별개의 클래스로 만들어서 관리를 한다고 하더라도 private멤버로 벡터를 가지며 Move, Attack 에 화살표만으로 association을 표시하는 것은 문제가 있다.
- association의 표시에서 *를 사용하여 여러 개의 Move, Attack 을 참조한다는 것을 표시하는 것으로 충분하다.
- 어찌 됬든 TaeKwonV, Atom, Sunguard등 Concrete Class에서 직접 Move, Attack 의 Concrete Class로 구현하지 않는 것이 주 목적이었다. 이를 인터페이스나 추상 클래스를 통해서가 아니라 직접 association하게 되면 명백한 OCP위반이다.
Observer Pattern
- 어떤 데이터가 실시간으로 업데이트 되어야 할 경우 클래스 간 서로 물리게 되는 문제가 발생한다.
- 데이터를 참조하는 클래스에서는 데이터를 참조하기 위해 엔티티 클래스에 association 한다.
- 엔티티 클래스에서는 데이터를 사용하는 클래스에 실시간 업데이트를 위해 association 한다.
- 데이터를 참조하는 클래스에서 엔티티 클래스로의 association은 문제가 되지 않는다.
- 하지만 엔티티 클래스에서 데이터를 사용하는 클래스로의 association은 OCP를 위반한다.
- 새롭게 데이터를 사용하는 클래스가 생성되었을 경우 엔티티 클래스에서 해당 클래스를 가리키는 인스턴스를 필요로 한다. 결국 이는 코드 수정을 요구하기 때문에 OCP위반이다.
- 직접 Control Class에 association하지 않으면서 데이터를 실시간으로 갱신하기 위해서는 Behavioral Pattern의 Observer Pattern을 적용하면 된다.
- 아래는 Observer Pattern을 적용하는 UML이다.
- ConcreteEntity가 AbstractEntity 를 구현하도록 설계하여 SRP를 준수한다.
- SRP : ConcreteEntity의 구현에 있어 단일 목적만을 가지고 구현해야 한다.
- AbstractEntity 는 Obserber 인터페이스에 association한다. 이를 통해 데이터의 변경이 일어났을 경우 update()를 호출하여 데이터를 참조하는 클래스들의 인터페이스에 알릴 수 있다.
- 데이터의 변경이 발생하였을 때, 데이터를 참조하는 클래스들은 Observer Interface를 구현하였으므로 AbstractEntity 의 update()호출에 의해 데이터를 실시간 변경을 업데이트 할 수 있다.
- 또한 각 Control클래스가 Observer인터페이스를 구현하면서 DIP, ISP를 준수한다.
- ISP : Interface Segregation Principle : 인터페이스를 쪼개서 필요한 기능만 구현
- DIP : Dependency Inversion Principle : 상위 모듈은 하위 모듈에 의존하면 안되고, 추상화는 실제 구현에 의존해서는 안된다.
- ConcreteEntity가 AbstractEntity 를 구현하도록 설계하여 SRP를 준수한다.