전체 글 669

[OOP] 스트래티지 패턴(Strategy Pattern)

디자인 패턴이란? 객체지향설계 과정에서 발생하는 문제들을 해결하기 위한 패턴(Pattern) 문제 상황 객체자향설계 중 '상속'은 한 가지 문제가 있다. 로봇 클래스를 상속하는 Atom 클래스와 TakwonV 클래스가 있다. 만약 자식 클래스로 Ironman 클래스가 추가 된다면 어떻게 될까? Ironman 클래스는 부모클래스의 메소드를 Override 한다. 문제는 TakwonV와 Ironman 클래스의 attack() 메소드가 소스 중복이 생기고 Atom클래스와 Ironman 클래스 사이에 move() 메소드에 소스 중복이 생긴다. 이처럼 자식클래스는 부모클래스의 메소드를 Override하면서 소스 중복이 생기고 이로인해, 유지보수가 힘들어 진다. 이와같은 상속의 문제를 해결하기 위해 등장한 디자인 ..

OOP/Design Pattern 2022.11.13

[MODERN JAVA] 동작 파라미터화 - 전략 디자인 패턴 ( Strategy Pattern )

변화에 대처 가능한 코드를 짜려면 어떻게 해야할까? 컴파일에 결정되는 코드가 아닌 런타임에 결정되는 코드를 짜야 한다. 대표적으로 동작 파라미터화(behavior parameterization)가 있다. 많은 데이터 중 원하는 데이터만 필터링 하려한다. 가볍게 데이터를 파라미터로 받아 조건문으로 필터링하면 된다. 하지만 요구사항은 바뀐다. 필터링 조건은 끊임없이 바뀌고 그럴 때마다 필터링하는 메소드도 복잡해진다. 요구사항이 변함에 따라 필터로직도 수없이 바뀐다. 그렇다면 우리는 어떻게 변화에 대응해야할까? 첫 번째 대응 방법은 '전략 디자인 패턴(Strategy Pattern)'이다. 전략 디자인 패턴은 문제해결을 위한 여러가지 전략이 존재할 때, 전략의 패밀리를 인터페이스로 구현하고 런타임시, 상황에 ..

JAVA/Modern JAVA 2022.10.24

[OOP] 피터 코드의 상속 규칙

객체지향 소프트웨어 개발의 대가 피터 코드(Peter Coad) 피터 코드는 상속의 오용을 막기 위해 5가지 상속 규칙을 내세웠다. 1. 자식클래스와 부모클래스는 '역할 수행' 관계가 아니어야 한다. 상속은 '추상화'를 구현한다. 추상화란 '공통된 특징'을 파악해 '인식의 대상'으로 삼는 행위이다. 달달하고 상큼한 것을 먹고 싶을 때, 우리는 '과일' 먹고 싶다라고 말한다. 바나나, 딸기, 수박, 파인애플 등등 '과일'이라는 단어가 없다면 무척이나 표현이 힘들어진다. 그러므로 추상화란 어떤 집단이나 집합의 '간판'과 같다. 그리고 객체지향설계에서 추상화는 상속으로 구현된다. 그런데 가끔 상속을 역할과 혼동하는 경우가 생긴다. 민수는 출근하면 회사원이다. 퇴근하면 운전자가 된다. 주말에는 아르바이트생이 된..

OOP/OOP Basic 2022.10.18

[OOP] 특수화

[OOP] 일반화(추상화) 일반화(추상화)는 객체지향 설계의 핵심이다. 일반화와 추상화는 사전적 정의로 구분될 수 있지만 굳이 구분 안 해도 별 탈 없다. 추상화와 일반화를 구분하는 것보다 더 중요한 것이 있다. 바로 lordofkangs.tistory.com 지난 포스팅에서는 일반화를 다루었다. 회원(MEMBER)는 VIP 회원과 일반 회원(Ordinary)의 일반화이다. VIP 클래스나 ORDINARY 클래스의 공통된 데이터에 대한 로직은 MEMBER 클래스에 접근하는 것이 좋다. 반면 VIP 할인과 같이, VIP만 해당되는 영역은 VIP만 따로 접근하는 것이 좋다. 여기서 요구사항이 추가되었다고 가정해보자. 지역(Local) 주민들은 기프티콘을 받는다. VIP이면서 지역주민일 수 있고 일반 회원이면..

OOP/OOP Basic 2022.10.18

[OOP] 일반화(추상화)

일반화(추상화)는 객체지향 설계의 핵심이다. 일반화와 추상화는 사전적 정의로 구분될 수 있지만 굳이 구분 안 해도 별 탈 없다. 추상화와 일반화를 구분하는 것보다 더 중요한 것이 있다. 바로, 일반화와 특수화를 구분하는 것이다. 일반화(추상화)는 공통된 특성이나 공통된 기능으로 묶는 것을 의미한다. 공통된 특성은 상속으로 구현되고 공통된 기능은 인터페이스로 구현된다. 어떤 관점을 가지냐에 따라 설계 방식이 달라진다. 사용자는 '키는' 기능을 하고 싶다. 근데 만약 전등에 직접 접근한다면 오로지 전등만 킬 수 있다. TV, 에어컨 기타 등등은 킬 수 없다. 이는 비효율적인 설계이고 유지보수에 좋지 못하다. 효율적인 설계를 하려면 사용자는 '키는' 기능에 접근해야한다. 예를 들어 리모컨이 있을 수 있다. p..

OOP/OOP Basic 2022.10.17

[OOP] 캡슐화

캡슐화(Encapsulation) 캡슐화는 요구사항 변경을 유연하게 만든다. 그 이유는 높은 응집도와 낮은 결합도를 구현하기 때문이다. 응집도는 모듈 내부의 구성요소가 얼마나 통일성 있는지를 나타낸다. 모듈 내부의 변수나 메소드가 서로 다른 목적과 역할을 가진다면 모듈의 응집도는 떨어지고 여러 요소에 영향을 많이 받는다. 즉 유지보수가 어려워진다. 1) 응집도 public class Computer{ private Mainboard mb; private CPU cpu; private Memory memory; private Phone phone; // 아무 관련 없는 객체 public Computer(){ this.mb = new MainBoard(); this.cpu = new CPU(); this.m..

OOP/OOP Basic 2022.10.17

[OOP] 의존관계

객체는 크게 두 가지로 구성된다. 1. 필드변수 2. 메소드 필드변수는 Heap Memory에 저장되므로, 객체가 가비지 컬렉터에 의해 제거 될 때까지 살아있다. 고로, 항시적 데이터는 필드변수에 저장한다. 이전 포스팅에서 다룬 연관관계, 집합관계, 합성관계는 다른 객체의 주소를 필드변수에 저장하는 관계로 언제든 참조 가능한 관계이다. 반면, 메소드에서 생성된 변수는 Stack Memory에 저장되므로, 메소드 호출기간 동안만 살아있다. 메소드 같이, 특정 기능을 수행할 때만 필요한 객체는 임시로 메소드 내 변수에 저장하는데, 이를 의존관계라 부른다. 의존관계는 두 가지 유형이 있다. 1. 객체를 메소드 인수로 받는 경우 public class Car{ public void fillGas(GasPump ..

OOP/OOP Basic 2022.10.12

[OOP] 합성관계와 집합관계

합성관계(Compostion)와 집합관계(Aggregation)는 전체와 부분을 나타내는 관계로 부분객체의 생성권한이 어디있느냐로 구분된다. 합성관계(Composition) 전체객체가 부분객체의 제어권을 갖는다. 예를 들면, 일체형 컴퓨터 같은거다. public class Computer{ private MainBoard mb; private CPU cpu; private Memory memory; public Computer(){ this.mb = new MainBoard(); //객체생성 this.cpu = new CPU(); // 객체생성 this.memory = new Memory(); //객체생성 } } Computer 객체가 생성될 때, MainBoard,CPU,Memory 객체도 생성된다. ..

OOP/OOP Basic 2022.10.12

[클린코드] 명령과 조회를 분리하라

함수는 두 가지 중 하나이다. 1. 명령 2. 조회 '명령'은 특정 행위(do)를 한다. '조회'는 특정 상태(state)를 조회한다. 그러므로 함수는 명령과 조회가 같이 있으면 안된다. 예를 들어, public boolean set(String userName, String password); 언뜻 보면 set 함수는 userName과 passWord를 받아 회원정보를 설정(do)하는 함수 인 것 같다. ( 명령함수) 그러나 Return 값을 보면 boolean이다. False나 True는 조회가 되었는지 여부를 리턴할때 쓰는 자료형이다. 즉, 명령과 조회가 혼합된 함수이다. 이런 함수는 혼란을 일으킨다. 고로 함수를 분리해주어야 가독성이 올라간다. if(attributeExists("userName"..

[알고리즘] 재귀호출(recursive call)이란?

'재귀호출(recursive call)'은 완전탐색을 구현할때 용이하다. 완전 탐색은 선형적 방식과 재귀적 방식(계층적) 으로 접근할 수 있다. 선형적 방식은 반복문을 돌려 하나씩 탐색하는 방식이다. 재귀적 방식(계층적)은 Top에서 Bottom으로 Down하며 모든 경우의 수를 탐색하는 방식이다. 그렇다면 어떤 경우에 어떤 방식을 사용해야 할까? 반복문을 사용하는 경우 완전탐색은 반복문을 사용하여 구현할 수 있다. 1 ~ 10개의 원소가 있다. 이중 특정 조건에 부합하는 4가지 원소를 찾으려 한다. 그럼 1부터 10까지 탐색을 해야하는데 '반복문'을 사용한다고 가정해보자. 4가지 원소로 구성된 한 조합을 찾아야 하므로 for문의 변수는 네 개가 필요하다. 반복문을 사용하는 경우 10개의 원소 중 조건에..