객체지향 프로그래밍과 디자인 패턴

조성현·2021년 5월 3일
0

객체지향은 프로그래밍 방법론이다. 즉, 정답은 아니란 이야기이다.
상황에 따라 객체지향 프로그래밍이 유리할 수도, 함수형 프로그래밍이 유리할 수 도 있다.
다만, 이런 트레이드 오프 관계를 이해하는 것은 프로그래머로서 통찰력을 갖게 해준다.

참고: https://www.yalco.kr/16_oodp/

📕 객체지향 개념

객체 = 데이터와 기능이 class로 캡슐화된 컴퓨터 자원의 묶음

📕 객체지향 특징

객체지향은 캡슐화, 정보은닉, 추상화, 상속성, 다형성이 특징이다.
다형성에서, 상속은 물려받는 것, 인터페이스는 장착하는 것

◼ 은닉성 (private, public)

내부 구조는 private으로 감춰놓고, 외부에서 조작할 수 있는 명령어만 public으로 공개

private = 해당 class만 접근 가능
protected = 해당 class 또는 이를 상속받은 class 접근 가능
public = 어떤 class든 접근가능

-> 외부에 의한 오류를 방지.
-> 남의 만든 기능을 일일히 뜯어볼 필요 없이 제공되는 기능 사용.

◼ 상속 (extends, super)

extends로 부모 class로부터 protected, public인 자원을 상속, super로 부모 클래스의 자원을 사용
자식 class를 위한 자원을 추가 가능
-> 비교적 추상적인 부모 클래스로부터 구체적인 자식 클래스 생성.

◼ 추상화 클래스 (abtract)

자식클래스들의 공통분모 역할의 class.
직접 객체를 선언하는 것은 불가능.

◼ 다형성 (Override)

부모 class에서 정의된 메소드가 자식 class에서 override를 통해 대체됨
-> 같은 명령어로 장착된 클래스의 메소드들을 실행 가능
-> 다만, 상하 관계가 뚜렷하기 때문에 두 부모를 지원하지 않는 언어가 있음.

◼ 인터페이스 (interpace, implements)

interface로 메소드를 선언해주고, implements로 각 클래스에 장착
-> 클래스마다 실행될 내용은 다를 수 있으나 같은 메소드들을 장착
-> 같은 명령어로 장착된 클래스의 메소드들을 실행 가능

📕 객체지향 디자인 패턴

◼ Singleton

프로세스에 특정 객체가 하나만 존재해야 할 때 사용 (ex. 설정)

  1. 정적으로(private static)으로 초기 변수를 null로 초기화 함수를 선언
  2. class가 처음 사용된다면 static 영역에 class를 할당 시킴.
  3. class 다음에 사용될 시에는 static에 있는 녀석을 반환.
  4. static 영역에 있는 한 녀석을 사용하게 된다.

-> 굳이 정적변수를 쓰지 않는 이유는, interface, lazy loading이 가능하기 때문
-> 멀티스레드에서 사용할 때는 신경써야함.(언어마다 방법이 다름)

◼ Strategy

옵션들마다의 행동들을 모듈화해서 독립적이고 상호 교체 가능해야 할 때 사용 (ex. 검색의 모드(이미지,뉴스,지도))

  1. interface로 메소드를 선언한 뒤
  2. interface를 장착해 같은 메소드에 각 옵션의 모듈을 작성
  3. 옵션 변경시에는 각 모듈을 선언해 할당시켜 적용

-> 각 모듈을 수정하고 관리하기 편함
-> 새 모듈을 추가하기 편함

◼ State

상태마다 할 일 + 상태 변경을 모듈화해서 관리해야할 때 사용 (ex. 버튼 토글)

  1. interface로 메소드를 선언한 뒤
  2. 각 상태 때 실행되야 할 일 + 상태 변경을 모듈화해 작성.
  3. 상태 변경을 해주었기 때문에, 다음에 같은 메소드가 실행되면 다른 모듈이 실행된다.

-> strategy와 비슷하지만, strategy는 지정된 메소드에 대해 각 모드를 실행시키나, state는 그 모드도 전환시킴.
-> 상태변경이 모듈안에서 일어날 지, class 안에서 if문으로 구별되 일어날지는 상황에 따라 선택.

◼ Command

다양한 명령을 모듈화할 때 사용 (ex. 로봇청소기(이동,회전,청소))

-> 다양한방법으로 구현 가능
1. 모드 변경에 따라 명령을 갈아 끼어넣기
2. 스위치를 올릴 때, 내릴 때, 각각 다르게 모듈화
3. 여러 명령을 목록으로 add해 실행
-> strategy와 비슷하지만, strategy는 같은 일을 하되 알고리즘이나, 방식이 갈아껴지는 것. command는 하는 일 자체가 다름.

◼ Adapter

interface가 서로 다른 class들을 같은 형식에서 실행시킬 때 사용.

  1. adapter class를 기존의 interface를 사용해 선언
  2. 바꿀 class를 선언하고 작동하고자 하는 method를 기존 interface에 맞춰 선언
  3. 다른 interface의 class를 사용할 때는 이 adapter를 적용해 사용.

-> 같은 method로 다른 interface의 class도 실행시킬 수 있다.

◼ Proxy

처리속도가 길거나 메모리를 많이 차지하는 class 대신에 간단한 일을 처리하는 class를 둘 때 사용 (ex. 썸네일 프리뷰)

  1. 실제 메소드와 proxy 메소드를 interface 선언
  2. 실제 class와 proxy class를 이 interface로 선언
  3. proxy class에서는 간단한 작업을 수행하며, 실제 class를 null로 두고 있다가.
  4. 실제 class가 필요할 때 비로서 lazy load처럼 실제 class를 선언해 할당하고,
  5. 실제 class는 시간 걸리는 작업을 수행.

-> 한번 실행된 실제 class는 계속 존재함으로 2차 동작을 막음.
-> 이외에도 여러방식으로 응용됨.

◼ Facade

여러 class들을 반복해서 사용한다면 이를 한 class의 메소드 안에 넣을 때 사용

-> 외벽안에 감춘다는 뜻으로, 과정에 신경쓰지 않을 수 있음

◼ Template-method

어떤 일을 수행하는 몇 가지 방법이 있는데, 그 전반적 과정에 공통된 절차가 있을 때 사용 (ex. 네이버지도,카카오지도)

  1. 공통된 과정의 추상화 class 선언.
  2. 상속받은 자식 class에서 각각의 메소드에 대해 각각의 방법을 override
  3. 실행시에는 같은 실행 메소드로 실행.

-> 같은 형식을 지닌 특정 작업들의 세부 방식을 다양화

◼ Decorator

class의 메소드들을 여러가지 두고 사용자가 필요에 따라 꺼내 쓸 때 사용. (ex. 전투기 슛팅게임의 무기)

  1. interface로 공통된 메소드 추가
  2. 추상화 class를 선언해 기본 method를 선언
  3. 자식 class들을 선언해 super로 부모의 기본 메소드를 실행시키고, 추가할 메소드를 추가함.
  4. 사용시에는 decorator class안에 기존 class를 인자로 넣고 실행

-> 객체가 생성자 변수로 다른 객체 안에 들어감으로서 실행하는 메소드의 행동이 추가됨.
-> 여러개 겹쳐서 사용하면 여러개 기능 추가

◼ Factory-method

factory 안에서 주어진 조건에 따라 적절한 객체를 생성해서 반환할 때 사용 (ex. component 라이브러리)

  1. 각 class에 공용으로 사용될 메소드를 가진 interface 선언 (ex. getComponent)
  2. interface를 장착한 class들 선언
  3. factory 선언 후 주어진 인자에 대해 각 class를 선언후 반환

-> 객체를 생성하는 곳을 일일히 찾을 필요없이 한곳에 수정하고 관리 가능
-> 유저가 내부에 복잡한 객체 생성을 몰라도 된다.
-> decorator와 함께 사용하면 다양한 조합을 쉽게 만들 수 있다.

◼ Abstract-factory-method

factory-method 안의 class처럼 factory도 다양하게 필요할 때 (ex. 다양한 테마의 component 라이브러리)

  1. 기존 팩토리를 추상 class나 interface로 만듬
  2. 이를 상속한 테마마다의 factory를 만듬

-> factory method에 추상화가 한 단계 더 들어감.

◼ Mediator

여러 class의 관계가 특정 event를 중심으로 복잡하게 얽혀있을 때 사용 (ex. 모드변경에 따른 화면 전환)

  1. listner 라는 interface를 선언.
  2. 이벤트를 받게 될 class에 이를 장착하고 받게될 이벤트에 따라 메서드 작성
  3. mediator class를 선언해, 안에 list와 반복문을 통해 listner들에게 알리는 함수 선언
  4. 작동시키고자 하자는 event class에 mediator를 set
  5. event class의 mediator의 list에 listner들을 추가

-> 여러개의 event에 같은 중재자를 두어 N대N 관계를 형성

◼ Composite

포함하는 것들과 포함되는 것들이 같은 방식으로 다뤄질 때 사용 (ex. 폴더)

  1. 공통적으로 사용될 메소드를 가지는 interface 선언
  2. 각 class마다 공통된 메소드에 대해 처리될 각각의 방법을 선언

-> 포함되어있는 부분들까지 모두 재귀적으로 적용되어질 수 있다. (ex. 폴더안의 파일,폴더들 삭제, 폴더안의 용량 구하기)

profile
Jazzing👨‍💻

0개의 댓글