디자인 패턴 – 객체지향 기본 개념

객체지향 모델링

디자인 패턴
소프트웨어를 설계할 때 전통적으로 자주 발생하는 문제에 대해서 누구나 재사용할 수 있도록 제시된 해결책

– 생성 패턴: 객체의 생성과 관련된 패턴
– 구조 패턴: 클래스를 조합해 더 큰 구조를 만드는 패턴
– 행위 패턴: 알고리즘이나 책임의 분배에 관한 패턴

체지향 모델링
모델: 현재 시스템 또는 앞으로 개발할 시스템의 모습을 가시화한 것
(시스템의 구조와 행위를 명세함)

모델은 추상화에 바탕을 두고 있다.
즉 특정 관점에서 관련이 있는 점은 부각하고 관련이 없는 것은 무시한다.
ex) 학생이 갖고 있는 많은 정보 중에 학교 앱이 필요한 정보는 (수강 과목, 지도 교수, 전공)이다. 반면, 혈액형이나 MBTI 등은 중요하지 않다.

UML (Unified Model Language)
대표적인 모델링 언어
ex) 구조를 나타내는 클래스 다이어그램, 행위를 나타내는 시퀀스 다이어그램

클래스 다이어그램
시스템의 정적인 구조를 표현하는 다이어그램
ex) 자전거의 안장, 바퀴, 체인, 핸들 등

시퀀스 다이어그램
시스템의 동적인 행위를 표현하는 다이어그램
ex) 자전거의 폐달을 밟으면 체인이 돌아가고, 체인이 돌아가면 바퀴가 돌아가고, 바퀴가 돌아가면 앞으로 전진함

클래스
동일한 속성을 가지고 동일한 행위를 수행하는 객체의 집합
ex) 동일한 꼬리를 가지고 동일하게 ‘야옹’ 소리를 내는 고양이 객체의 집합

UML의 클래스 표현
클래스를 세 부분으로 나누어 표현한다.
1. 클래스 이름, 2: 클래스 속성, 3:클래스의 메소드
<경우에 따라서 세 가지 중 한 두가지만 존재할 수도 있다>
<메소드의 내용은 시퀀스 다이어그램으로 표현한다>

UML에서 제공하는 클래스들 사이의 관계

집합 관계

  • 집약(Aggregation): 전체를 나타내는 객체와 부분을 나타내는 객체의 lifetime이 독립적인 경우
    ex) ppt에서 wave효과를 전체 페이지에서 같이 사용한다고 할 때, page와 wave는 집약 관계이다.
    -> page가 사라져도 wave는 사라지지 않는다.
  • 합성(Composition): 전체를 나타내는 객체와 부분을 나타내는 객체의 lifetime이 종속적인 경우ex) ppt에서 page와 element는 합성 관계이다. -> page가 사라지면 element도 사라진다.

연관 관계와 의존 관계
연관 관계는 지속적인 관계이지만, 의존 관계는 잠깐만 사용하는 관계이다.
ex) 사람은 차를 지속적으로 이용하므로 연관 관계이다. 차는 가스 펌프를 필요할 때만 사용하므로 의존 관계이다.

접근제어자
public(+), private(-), protected(#), package(~)
– public: 어떤 클래스의 객체에서든 접근이 가능
– private: 이 클래스에서 생성된 객체들만 접근이 가능
– protected: 이 클래스와 동일 패키지에 있거나 상속 관계에 있는 하위 클래스의 객체들만 접근 가능
– package: 동일 패키지에 있는 클래스의 객체들만 접근 가능


객체지향 원리

1. 추상화
어떤 영역에서 필요로 하는 속성이나 행위를 추출하는 것
ex) 사람의 혈액형, 나이, 성별 같은 속성을 모아서 환자라는 클래스를 제작함,
사람의 학번, 지도교수, 학점 같은 속성을 모아서 학생이라는 클래스를 제작함

2. 캡슐화
1) 연관있는 필드 변수와 메소드를 클래스로 묶는 것
2) 내부 구현 내용을 외부에 감추는 것 (=) 정보 은닉을 통해 낮은 결합도를 가지게 하는 것
ex) 자동차의 내부 동작 원리를 몰라도 자동차 사용법을 익히면 운전이 가능하다.
사용자는 자동차 API의 원리를 몰라도, API를 사용할 수 있다.

관계가 약하면 다른 이가 수정한 코드 때문에 내가 코드를 바꿀 필요가 없다.

예를 들어, 스택 자료구조를 구현한 Stack 클래스가 있고, 스택을 사용하는 StackList 클래스가 있다고 하자.
StackList에서 Stack 객체의 top, stackSize, itemArray 변수를 직접 수정한다면 무슨 일이 일어날까?
만일 Stack 클래스가 ArrayList를 사용하도록 내용이 변경된다면 StackList의 내용도 바꿔야 되는 것이다.
그런데 Stack 클래스에서 push, pop함수를 제공하고, StackList에서 push, pop함수를 이용한다면 어떨까?
만일 Stack 클래스가 ArrayList를 사용하도록 내용이 변경되더라도 StackList는 push, pop함수를 그대로 사용할 수 있다.

3. 일반화
한 클래스가 다른 클래스를 포함하는 상위 개념일 때 사용하는 것
ex) 세탁기, TV, 식기세척기는 가전제품이다.

일반화를 이용하면, 코드의 재사용 뿐 만 아니라 불필요한 코드의 수정도 막는다.

int computeTotalPrice(LinkedList<Fruit> f){
    int total=0;
    Iterator<Fruit> itr=f.iterator();

    while(itr.hasNext()){
        Fruit curFruit = itr.next();
        total=total+curFruit.calculatePrive();
    }
    
    return total;
}

전체 과일을 아우르는 ‘과일’이라는 클래스를 이용하면 새로운 과일이 와도 코드를 수정하지 않아도 된다.
그렇지 않고 과일마다 조사하는 switch문을 이용하면, 새로운 과일(ex. 키위)가 나오면 코드를 추가해야 된다.

[위임]
나의 클래스가 일을 하지 않고, 다른 클래스 일을 하도록 하는 것
ex) stack의 push 기능을 만들 때, ArrayList 클래스의 add 기능을 사용해서 구현할 수 있다.

일반화는 disjoint해야 좋다!
자식 클래스는 다른 자식 클래스와 교집합이 없어야 좋다.
ex) 환자와 학생의 속성은 겹치지 않는다.

일반화는 complete해야 좋다!
자식 클래스들의 합집합은 부모 클래스여야 좋다.
ex) 남자와 여자를 합치면 사람이다.

4. 다형성
서로 다른 클래스의 객체가 같은 메시지를 받았을 때, 각자의 방식으로 동작하게 하는 것
ex) 육상선수와 수영선수가 Action이라는 메시지를 받았을 때 서로 동작이 달라야 한다.
(육상 선수는 트랙 위를 달리고, 수영 선수는 물 속에 뛰어들어 수영을 해야함)


상속 규칙

1. 아래와 같은 일반화 관계가 되면, 운전자는 회사원이 될 수 없고 회사원은 운전자가 될 수 없다.

2. 아래와 같이 집약 관계가 되면, 사람이 두 역할을 모두 수행할 수는 있지만, 새로운 역할이 온 경우 ‘사람’ 클래스를 수정해야 된다.

-> 사람과 운전자, 사람과 종업원의 관계를 약하게 만들면 된다. (Encapsulation)
// 클래스를 만드는 것도 캡슐화(Encapsulation)라고 하지만, 이미 존재하는 클래스간의 관계를 약화하기 위해 클래스를 재정의하는 것도 Encapsulation이다.

3. Encapsulation을 하기 위해 종업원과 운전자를 일반화해서 역할이라는 클래스를 만든다.
운전자와 종업원은 역할을 상속한다.

class Person{
	private Role r;
	
	public void setRole(Role r) {
		this.r=r;
	}
	
	public Role getRole() {
		return this.r;
	}
	
	public void doIt() {
		r.doIt();
	}
}

abstract class Role{
	public abstract void doIt();
}

class Driver extends Role{
	public void doIt() {
		System.out.println("Driving");
	}
}

class Worker extends Role{
	public void doIt() {
		System.out.println("Working");
	}
}

public class test{
   public static void main(String[] args) {
	   Person p = new Person();
	   p.setRole(new Driver());
	   p.doIt();
	   p.setRole(new Worker());
	   p.doIt();
   }
}


Leave a Reply

Your email address will not be published. Required fields are marked *