본문 바로가기
Lecture

디자인 패턴을 배워야 하는 이유, 객체지향 설계와 SOLID, 클래스 다이어그램

by Renechoi 2023. 7. 5.

 

디자인 패턴에 대해 알아보자. 

 

 

디자인 패턴이 생겨난 이유 

- 소프트웨어를 재사용할 수 있고, 유연하고 확장성 있고, 유지 보수 만들기는 어려운 일이다.

- 실제 개발보다 유지 보수하는데 더많은 시간과 노력이 들어간다. 

- 아무리 뛰어난 사람이 만들어도 수정은 반드시 필요하게 된다! < 시대 변화, 고객 요구 

 

디자인 패턴이란? 

- 성공적인 설계라는 것은 존재한다.

- 건축에도 패턴이라는 것이 존재하듯이... 

- 네 명의 학자 (Gang of Four)가 기존의 많은 사례와 시스템 등을 분석하여 좋은 설계는 이런 것이다, 23개 패턴 제안 

- 패턴 구분 : 생성, 구조, 행동 

 

 

디자인 패턴은 규칙은 아니지만

- 매직은 아님

- 언어 종속적이지 않음-> 일반적 사용!

- 좋은 설계에 대한 제안 

- 커뮤니케이션에도 도움이 된다. 

 

 

 

객체지향 프로그래밍과 객체지향 설계 

 

추상화 

- 어떤 구체적인 사물, 사람, 무언가에 대해 특성들을 추출하기

 

캡슐화

- 외부에서 접근할 수 있는 방법에 대한 내용

- 사용하는 코드의 세부적인 사항을 알릴 필요가 없음 - 클라이언트쪽에서 알 필요가 없음 

- 단순한 접근을 제공하여 오류의 여지를 감소시킴 

 

상속성

- 재사용 접근으로 접근하면 안된다! -> 일반적인 개념의 객체보다 구체적인 개념의 객체 관계를 표현 

- employee라고 하면, 직원, 임원, 정규직 등등... -> 일반 -> 구체 

- 하위 클래스에서 재정의할 수 있음 

 

다형성 

- 상속을 기반으로 다형성을 구현할 수 있다

- 같은 메시지, 같은 구현에 대해 각 객체가 다른 표현과 결과를 나타냄

- 클래스의 상속, 인터페이스 구현으로 상위 타입으로 업캐스팅 

 

 

설계 부분에서 여러 가지를 고민할 수 있다. 휴리스틱한 측면에서 

- abstract냐 concrete냐 

- class Inheritance냐 object composition이냐

- 인터페이스 inheritance vs implementation inheritance 

 

 

좋은 설계는 응집도는 높게 결합도는 높게 

 

 

 

SOLID 

 

1. 단일 책임 원칙 (Single Responsibility Principle) 

- 역할, 책임, 협력 -> 어떤 기능을 하고 어떻게 수행하고 어떻게 메시지를 주고받을 것인지에 대한 문제 

- 하나의 클래스/메서드는 하나의 기능만을 구현하도록 한다. 

 

2. 개방 폐쇄의 원칙(Open-closed Principle) 

- 자신의 수정에 대해서는 유연하고 다른 클래스가 수정 될 때 영향 받지 않는다.

- 인터페이스나 추상클래스를 통해 접근하도록 함 

- e.g. 자바 JDBC, I/O stream -> 상위 클래스를 인터페이스로 정의하고 connection을 정의하는 모든 것들을 추상 메서드로 정의해놓은다. Oracle, Ms 등등... 각 DB사들이 해당 인터페이스를 구현해야 한다. 

 

3. 리스코프 치환 원칙(Liskov Subsititution Principle) 

- 하위 클래스는 항상 상위 클래스로 교체될 수 있어야 한다. -> 상위 클래스의 개념을 플러스 알파로 

- 즉 상속 관계는 IS-A 관계이므로, 상위 클래스에서 제공되는 여러 기능은 하위 클래스가 모두 사용 가능해야 한다. 

 

4. 의존성 역전 원칙 (Dependency Inversion Principle) 

- A가 B 클래스를 사용한다 

- 의존 관계는 구체적인 것보다 추상적인 것에 의존한다. -> 인터페이스 or 추상 클래스 

 

5. 인터페이스 분리 원칙 (Interface Segretation Principle) 

- 제공하는 기능에 대한 인터페이스에만 종속되어야 한다.

- 하나의 객체가 여러 기능을 제공해야 한다면 (단일 책임 원칙 위배) -> 이때 클라이언트가 사용할 수 있는 여러 인터페이스로 분리하여 제공하면 클라이언트가 사용하지 않는 기능에 종속되지 않을 수 있다. 

 

 

클래스 다이어그램 

객체 지향 프로그래밍에서 여러 클래스 상호간 협력 관계를 나타내는 다이어그램 

 

https://docs.staruml.io/working-with-uml-diagrams/class-diagram

 

https://www.stickyminds.com/article/class-diagrams

 

연관 관계 

- 클래스 상호 간 연관관계

- 단방향 : 화살표(->)

- 양방향: 직선(-)

- 클래스 간의 연관된 개체 수를 표현해야 하는 경우는 선의 끝 쪽에 다중성을 나타낸다. -> 몇 개를 쓰는지 

 

public class Student {
   int student Id;
   String name;
   ArrayList<Subject> subjectList;
}

 

 

 

집합 관계 (composition, aggregation) 

- 연관관계의 특별한 경우 -> 포함관계를 나타냄 

- 집약:

   - 빈 마름모 표시 

   - 전체 객체와 부분 객체 라이프 타임에 독립적 -> 포함하는 객체가 사라져도 포함되는 객체가 사라지지 않는 경우

- 합성 

   - 채워진 마름모로 표시

   - 사라지면 같이 사라짐 

 

 

 

의존관계 (dependency) 

- 연관 관계보다 짧은 life time 

- 프로그램 내에서 참조 변수가 매개변수나 지역 변수로 구현 

- 점선으로 나타냄 

 

class Student {

    int money;
...
    public void takeBus(Bus bus) {
		  bus.take(1000);
		  this.money -= 1000;
		  
	 }
	    
	public void takeSubway(Subway subway) {
		  subway.take(1500);
		  this.money -= 1500;
	 }
}

 

즉 의존 관계는 매개 변수로 들어오는 경우

 

 

 

일반화 관계 

- 상속을 의미

 

 

 

실체화 관계

- 인터페이스와 구현체 

 

 

 

접근 제어자 표시 

- public: +

- protected: *

- default: ~

- private: - 

 


참고자료

- 패스트 캠퍼스 (박은종의 객체지향 설계를 위한 디자인패턴 with 자바)

 

 

 

 

 

 

반응형