IT 공부/객체지향 설계 공부16 동적 타입 언어와 정적 타입 언어의 차이점 (덕 타이핑) 0. 서론: 객체와 타입 객체지향에서 객체를 구현하는 주요 문법은 클래스다. 클래스는 많은 오해가 있다. 대표적인 예시가 바로 클래스를 붕어빵을 만드는 틀로 묘사하는 것이다. 붕어빵틀 비유는 클래스라는 문법 장치를 객체의 구현 코드로 인식하기 때문에 발생하는 오해다. 그러나 클래스는 객체를 구현하기 위한 코드가 아니라, 객체의 타입(type)을 구현하기 위한 코드다. 객체의 타입과 클래스 문법에 대한 자세한 설명은 책에서 잘 기술되어 있다. (링크) 여기서 간단히 요약하자면, 객체의 타입(type)이란 객체(object)를 분류(classify)하기 위한 추상화/일반화된 개념(concept)이며, 클래스 문법은 바로 이 개념, 즉 타입(type)을 구현하는 코드라는 것이다. 특정 클래스로 분류될 수 있는.. 2023. 12. 13. 인터페이스 분리 원칙(ISP) 제대로 이해하기 인터페이스 분리 원칙(Interface Segregation Principle)은 처음 내가 SOLID 원칙을 공부했을 때 가장 납득하기 힘들었던 원칙이었다. 대부분의 교과서와 강의가 SOLID 원칙을 변경의 용이성 관점에서만 설명하기 때문에, 객체지향이 지향하는 관점과 사고방식에 대해 몰랐던 당시의 나로선 ISP를 100% 납득할 수 없었다. "클래스가 있는데 그대로 쓰지, 왜 굳이 인터페이스를 또 만들어야 하는거지? 굳이 나누는 것이 의미가 있나?" 라고 생각했다. 물론 인터페이스를 나누는 것이 유용해 보이기는 했지만, 딱 그 뿐이었다. 유용성 이상으로 ISP를 지켜야 하는 이유를 몰랐다. "의존하지 않는 메소드가 있으면 그냥 안 쓰면 그만 아닌가?" 라고 생각했었다. 유용하다는 것은 달리 말하면 그.. 2023. 12. 11. 프레임워크와 라이브러리의 차이 (의존성 역전 원칙) 프레임워크와 라이브러리는 모두 모듈로서 제공된다. 그래서 표면적으로는 아무런 차이가 없는 것 같다. 하지만 서로 다르다. 개발자가 작성한 코드는 프레임워크가 호출한다. 반대로 라이브러리는 개발자가 작성한 코드가 호출한다. 그러나 더욱 심도 깊게 들어가면 본질적인 차이가 하나 있다. 그것은 바로 "의존성 역전(Dependancy Inversion)" 원리다. 1. 의존성 역전 (제어 역전) 의존성 역전에서 중요한 단어는 '역전'되었다는 표현이라고 나는 생각한다. 물론 내용적 측면을 다루는 단어는 "의존성" 이다. 하지만 DI는 "역전"되었다는 사실을 더욱 강조한 표현이다. 역전이라는 표현은 제어흐름과 소스코드 의존 방향에 대한 전통적인 관점을 역전시켰다는 의미로서의 역전이다. 따라서 역전이라는 단어를 이해.. 2023. 12. 9. 추상 데이터 타입 vs 객체지향의 객체 ( ※ 출처 - by 조영호 챕터7 ) 1. 추상 데이터 타입 추상 데이터 타입(Abstract Data Type)은 개발자가 필요로 하는 데이터 타입을 추상적으로 표현하고 이것과 관련된 연산을 구현한 새로운 데이터 타입을 말한다. 본래 타입(type)이란, 어떤 값에 대한 의미와 함께 그것을 가지고 할 수 있는 연산이 무엇인지 제공한다. 따라서 추상 데이터 타입(ADT)이라고 말했으나, 프로그래밍 언어에서 제공해주는 기본 데이터 타입도 같은 데이터 타입이다. 단지 추상 데이터 타입은 개발자가 직접 정의할 수 있다는 점에서 다를 뿐이다. ADT는 좋은 프로그램의 밑거름이 된다. 절차적(Procedural) 프로그래밍이 프로시저(함수)를 중심으로 원하는 기능을 분해하고 통합하는 식이라면, ADT는 개념 즉.. 2023. 12. 8. 훌륭한 인터페이스의 특징 (오브젝트 6장) 1. 디미터 법칙 (데메테르 법칙) 디미터의 법칙은 연속적인 메소드 호출을 하지 말라는 조언으로 설명된다. 하지만 이 법칙을 교조적으로 수용해 연속적인 메소드 호출을 무조건 금지해서는 안 된다. 디미터 법칙은 캡슐화 원칙과 관련이 있고, 따라서 특별한 경우에는 연속적인 메소드 호출이 더 나은 디자인일 수도 있다. 캡슐화란 인터페이스 뒤로 구현의 상세 사항을 전부 숨기는 것을 말한다. 적절하게 인터페이스가 설계되었다면, 내부 구현 정보를 최대한 숨겨 독립적이고 자율적인 객체를 만들 수 있다. 만약 인터페이스를 적절하게 설계하지 않고 내부의 구현 정보를 드러내면 어떻게 될까? 아래와 같은 코드를 생각해보자. public class Screening { private Movie movie; public Mov.. 2023. 12. 8. 객체지향 언어로 절차적 프로그래밍을 하는 문제 일반적으로 절차적 프로그래밍은 데이터와 그 데이터를 처리하는 함수를 분리시킨다. 따라서 데이터가 변경되는 경우 필연적으로 함수도 변경해야 한다. 그리고 함수를 변경하면 다시 그 함수를 사용하는 모듈도 변경되어야 한다.. 이렇게 데이터의 수정으로 인해 변경이 위로 파급된다. 자바와 같은 객체지향 언어를 사용한다는 이유로 객체지향 설계가 완성되는 것은 아니다. 어쩌면 절차적 프로그래밍 언어보다 더 이상한 코드가 만들어질 수도 있다. 특히 데이터의 구현을 중심으로 놓고 보는 관점은 아무리 OOP 언어를 사용한다고 해도 잘못된 설계를 낳을 수 있다. 클래스를 만들어 데이터와 메소드를 private 접근 제어자로 숨긴다고 해도 getter, setter, 간단한 데이터 조작 연산의 남발은 이를 무색하게 만든다. .. 2023. 12. 7. 데이터 중심 설계는 캡슐화, 결합도, 응집도를 해친다 (오브젝트 4장) 1. 좋은 객체의 특성 개념 정리 1-1. 캡슐화 내가 처음 자바를 배웠을 때, 캡슐화란 "데이터와 프로세스를 한데 묶어 편의성을 제공해준다"는 식으로 배웠던 기억이 있다. 그때 나는 막 C언어의 절차적 프로그래밍 스타일만 알고 있었기 때문에 캡슐화를 정말 말 그대로 알약과 같은 것이라고 생각했다. 데이터와 프로세스를 한데 묶는 기법 정도로 여겼다. 그러나 캡슐화는 편의성 개념과는 거리가 멀다. 캡슐화는 정보 은닉의 일종으로서, 객체의 내부 구현을 외부로부터 숨기기 위한 전략 중 하나다. 여기서 중요한 요점은 객체의 내부 구현을 왜 숨겨야 하는가다. 이 질문에 답하기 위해서는 객체란 무엇인지 아는 것으로부터 출발해야 한다. 객체지향 소프트웨어에서 객체란 특정 기능을 수행해주는 작은 프로그램과 같다. 절차.. 2023. 12. 7. 책임과 역할에 대한 상세한 이야기 (오브젝트 3장) 1. 역할, 책임, 협력 조영호님의 에서는 객체지향의 핵심 원칙을 역할, 책임, 협력의 구조로 소개한다. 간단히 말해 소프트웨어를 각자의 '책임'을 수행하며 서로 '협력'하는 '역할'들로 명세를 짜는 것이다. 역할과 책임에 대한 구체적인 실천은 런타임에 '객체(object)'가 수행한다. 이미 위 포스팅 링크에서 많은 내용을 정리했다. 따라서 여기서는 같은 저자의 챕터 3장에 나오는 설명 중 새롭게 알게 된 사실만 따로 정리하려 한다. 2. 책임 할당: 정보 전문가 패턴(Information Expert) 좋은 객체지향 설계의 핵심은 책임을 적절한 객체에게 할당하는 것이다. 크레이그 라만(Graig Larman)은 객체의 책임을 크게 하는 것(doing)과 아는 것(knowing)의 두 가지 범주로 나누.. 2023. 12. 7. 하이브리드 커플링과 오브젝트 1. 변수를 한 가지 목적으로만 사용하라. 책의 제 10장. 변수 사용 시 고려할 사항들에는 다음과 같은 조언이 있다. 변수가 한 가지 이상의 목적으로 사용되는 것은 그 변수를 만든 개발자는 몰라도, 그 변수를 읽고 코드를 이해해야 하는 다른 개발자에게는 추론을 강제한다는 점에서 나쁜 코드다. 변수를 한 가지 이상의 목적으로 사용하는 사례 중 하나는 "변수의 값에 숨은 의미를 부여하는 습관"이다. 이를 "하이브리드 커플링"이라고 부른다. 예를 들면 다음과 같다. pageCount 변수의 값은 출력된 페이지 수를 나타낸다. 만약 이 값이 -1이면 오류가 발생한 것이다. memberID는 회원의 식별 고유번호를 나타낸다. 그런데 이 값이 5000 이상이면 연체된 계정이다. 1000 이하이면 관리 계정이다. .. 2023. 12. 7. 이전 1 2 다음