본문 바로가기

개발관련

객체 지향 원리와 이해

반응형

개요

객체 지향의 원리와 이해에 대해서 알아보자.

 


기계어

인류 최초의 프로그래머들은 꺼진 상태와 켜진 상태를 각각 0과 1로 해석할 수 있는 백열전구(혹은 진공관)를 이용해 프로그램을 작성했다.

 

<동일한 1+3에 대한 명령>

  • 애드삭(EDSAC)
    • 01010101 00000001 00001001
  • 유니박(UNIVAC)
    • 11011100 00011000 10011000

 

특징

  • 이기종 간의 명령어(기계어)가 달랐음.
  • 이유는 CPU가 다르기 때문.
    • CPU가 해석하는 2진수가 달랐다.

 


어셈블리어

기계어의 명령들을 일상 용어로 표현하고 이걸 기계가 알 수 있는 기계어로 변역하게 하면 어떨까?

 

어셈블리어

  • 니모닉(Mnemonic)과 기계어의 일대일 대칭 코드표
  • CPU마다 기계어가 다르기 때문에 CPU별로 각자의 어셈블리어도 달랐음.
    • 즉, 이기종 간 어셈블리어가 달랐음.
    • 예:
      • 에드삭
        • 1+3 ⇒ add 1, 3
      • 유니박
        • 1+3 ⇒ plus 1, 3
  • 어셈블러(Assembler)
    • 어셈블리어를 기계어로 번역해주는 소프트웨어

 


C 언어 : One Source Multi Object Use Anywhere

C 언어의 등장

 

기계어, 어셈블리어, C 언어 비교

이름 기계어 어셈블리어 C언어
개발자의 코딩 0과 1의 나열 일상 단어 사용 수학적 기호 사용
소스 파일 기종마다 하나씩 기종마다 하나씩 기종이 몇개든 단 하나
목적 파일(기계어) 소스 그 자체 어셈블러로 소스를 번역해 생성 컴파일러로 소스를 번역해 생성
기계어 비교   기계어와 1:1 대응하는 니모닉 기계어와 m:n 대응하는 수학적 기호

 

 

One Source : 하나의 C 소스 파일만 작성

Multi Object : 기종마다 하나씩 기계어 목적 파일을 생성

Use Anywhere : 모든 컴퓨터에서 실행 가능

 

 

어셈블리어라면 같은 일을 하는 프로그램의 소스 파일을 각 기계의 종류만큼 만들어야 했음.

즉, 멀티 소스였음.

 

C 언어는 소스 파일을 단 하나만 만들고 이 하나의 소스 파일을 각 기계에 맞는 컴파일러로 컴파일만 하면 각 기계에 맞는 기계어 목적 파일이 만들어짐.

즉, 원 소스 멀티 유즈임.

 

어셈블리어와 비교했을때 가독성 또한 좋아짐.

 


Java : Write Once Use Anywhere

Java의 등장

 

기계어, 어셈블리어, C 언어, Java 비교

이름 기계어 어셈블리어 C언어 Java
개발자의 코딩 0과 1의 나열 일상 단어 사용 수학적 기호 사용 수학적 기호 사용
소스 파일 기종마다 하나씩 기종마다 하나씩 기종이 몇 개든 단 하나 기종이 몇 개든 단 하나
목적 파일(기계어) 소스 그 자체 어셈블러로 소스를 번역해 생성 컴파일러로 소스를 번역해 생성 기종이 몇 개든 단 하나의 JVM용 기계어 생성
기계어 비교   기계어와 1:1 대응하는 니모닉 기계어와 m:n 대응하는 수학적 기호 기계어와 m:n 대응하는 수학적 기호
비고   기종별 어셈블러 필요 기종별 컴파일러 필요 단 하나의 컴파일러만 필요, 기종별 JRE 세팅 필요 (한번만 설치해 주면 됨)

 

  • Java에서 가상 머신(Virtual Machine)이 등장함.
    • 컴파일러를 기종별로 따로 구매하지 않아도 됨.
    • JDK(Java Development Kit)으로 Java 개발 및 javac로 컴파일 ⇒ Java 목적 파일 생성됨
    • 각 기종에 맞는 JVM(Java Virtual Machine)이 돌아가고 그 안에서 JRE(Java Runtime Environment)가 Java 목적 파일을 해석하여 구동.

 


프로그래밍 언어의 변천사

정리해보자.

기계어

  • 개발자를 사랑하기에는 너무 초창기 기술이었다.
  • 탄도의 궤적은 계산해줬다.

어셈블리어

  • 인간의 언어로 프로그램 작성이 가능하게 해줬다.

C

  • 하나의 소스로 이기종 간에 이식성을 확보했다.

C++

  • 객체 지향 개념을 도입했다.
  • 인간적인 사고의 프로그래밍 방식이다.

Java

  • 한 번의 컴파일로 이기종 간에 이식성을 확보했다.
  • 포인터에 대한 개념 없이 프로그래밍을 가능하게 했다.

Spring Framework

  • 기술이 인간에 대한 완전무결한 사랑을 꿈꾸다!
  • 거대함 속의 단순함과 완벽함, 그리고 유연함!
  • 아주 작고 작은 끈이 이 우주의 모든 물질을 구성하며, 그 성질 또한 지배한다는 끈 이론처럼 스프링은 IoC/DI, AOP, PSA라고 하는 객체 지향의 베스트 프랙티스만으로 아무리 거대한 프로그램이라도 쉽게 구현할 수 있음을 보여준 프레임워크다. 단, IoC/DI, AOP, PSA 안에 녹아든 이전 기술들의 개발자 사랑을 이해해야 스프링 프레임워크도 온전히 이해할 수 있다.

 


Java 메모리 구조

  • 스태틱 영역(Static) : 클래스들의 놀이터
    • JVM 종료 시 메모리 해제
  • 스텍 영역(Stack) : 메서드들의 놀이터
    • 스텍 프레임 소멸 시 메모리 해제
  • 영역(Heap) : 객체들의 놀이터
    • 가비지 컬렉터에 의해 메모리 해제

 

변수의 위치

변수는 스태틱 영역, 스택 영역, 힙 영역 중 어디에 있는걸까?

정답은 세 군데 모두 이다.

 

지역 변수는 스택 영역에서 일생을 보낸다.

그것도 스택 프레임 안에서 일생을 보낸다.

따라서 스택 프레임이 사라지면 함께 사라진다.

 

클래스 멤버 변수는 스태틱 영역에서 일생을 보낸다.

스태틱 영역에 한번 자리잡으면 JVM이 종료될 때 까지 고정된(Static) 상태로 그 자리를 지킨다.

 

객체 멤버 변수는 힙 영역에서 일생을 보낸다.

객체 멤버 변수들은 객체와 함께 가비지 컬렉터라고 하는 힙 메모리 회수기에 의해 일생을 마치게 된다.

 

이름 다른 이름 사는 곳(T 메모리)
스태틱(Static) 변수 클래스 [멤버] 속성, 정적 변수, 정적 속성 등 스태틱 영역
인스턴스 변수 객체 [멤버] 속성, 객체 변수 등 힙 영역
로컬(Local) 변수 지역 변수 스택 영역 (스택 프레임 내부)

 

Java 메모리 예제 코드

Java 메모리 : 예제 1 (변수와 메모리)

Java 메모리 : 예제 2 (블록 스택 프레임)

Java 메모리 : 예제 3 (메서드 스택 프레임)

Java 메모리 : 예제 4 (전역 변수와 메모리)

Java 메모리 : 예제 5 (멀티 스레드 / 멀티 프로세스)

Java 메모리 : 예제 6 (인스턴스, 힙 영역)

Java 메모리 : 예제 7 (상속과 T메모리)

Java 메모리 : 예시 8 (다형성과 T메모리)

 

 


객체 지향의 4대 특성

캡슐화(Encapsulation)

상속(extends)

추상화(Abstraction)

다형성(Polymorphism)

 

Tips!

쉽게 "캡상추다" 로 외울 수 있다!

 

객체란?

  • 세상에 존재하는 모든 것은 사물, 즉 객체(Object)다.
  • 객체는 세상에 존재하는 유일무이한 사물이다.
  • 각각의 사물은 고유하다. (예: 김연아, 홍길동, 뽀로로)
  • 사물은 속성을 갖는다. (예: 이름, 나이, 성별)
    • 속성은 값이다.
  • 사물은 행위를 갖는다. (예: 먹다, 자다, 놀다, 노래하다)
    • 행위는 메서드다.

 

클래스와 객체의 관계

클래스 : 객체

펭귄 : 뽀로로

사람 : 김연아

클래스 : 분류, 집합 같은 속성과 기능을 가진 객체를 총칭하는 개념

객체 : 세상에 존재하는 유일무이한 사물

클래스

  • 클래스는 분류에 대한 개념이지 실체가 아니다.
  • 클래스 설계에서 추상화가 사용된다.
  • 클래스 설계를 위해서는 애플리케이션 경계(Context)부터 정해야 한다.
    • 내가 만들고자 하는 애플리케이션은 어디에 사용될 것인가?
      • 사람 클래스
        • 병원 애플리케이션 → 환자
        • 은행 애플리케이션 → 고객
  • 객체 지향에서 추상화의 결과는 클래스다.
  • 상속을 통한 추상화, 구체화
  • 인터페이스를 통한 추상화
  • 다형성을 통한 추상화
  • 클래스는 객체를 만들어내는 '팩터리(=공장)' 이다.

 

인스턴스(Instance)란?

클래스를 이용해 Object를 만들었다는 것을 강조할 때는 Object 라는 표현보다는 클래스의 인스턴스(Instance)라는 표현을 사용한다.

인스턴스는 new 명령어로 인해 클래스 객체가 스택 영역 내 스택 프레임으로 할당 되었을 때를 명칭한다.

 


객체 지향 설계 5원칙(SOLID)

단일 책임 원칙(SRP: Single Responsibility Principle)

개방 폐쇄 원칙(OCP: Open Closed Principle)

리스코프 치환 원칙(LSP: Liskov Substitution Principle)

인터페이스 분리 원칙(ISP: Interface Segregation Principle)

의존 역전 원칙(DIP: Dependency Inversion Principle)

 

결합도와 응집도

좋은 소프트웨어 설계를 위해서는 결합도(Coupling)는 낮추고 응집도(Cohesion)는 높이는 것이 바람직하다.

결합도는 모듈(클래스) 간의 상호 의존 정도로서 결합도가 낮으면 모듈 간의 상호 의존성이 줄어들어 객체의 재사용이나 수정, 유지보수가 용이하다.

응집도는 하나의 모듈 내부에 존재하는 구성 요소들의 기능적 관련성으로, 응집도가 높은 모듈은 하나의 책임에 집중하고 독립성이 높아져 재사용이나 기능의 수정, 유지보수가 용이하다.

 

SOLID는 객체 지향 프로그램을 구성하는 속성, 메서드, 클래스, 객체, 패키지, 모듈, 라이브러리, 프레임워크, 아키텍처 등 다양한 곳에 다양하게 적용되는 것이기에 막상 SOLID가 적용됐는지 아닌지 애매모호하거나 보는 사람의 관점에 따라 다르게 해석될 수 있는 소지가 있음을 밝혀둔다. SOLID 자체는 제품이 아닌 개념이기에 그렇다.

 

SOLID가 개념이긴 하지만 우리가 만드는 제품, 즉 소프트웨어에 녹여 내야 하는 개념이다.

SOLID를 잘 녹여낸 소프트웨어는 그렇지 않은 소프트웨어에 비해 상대적으로 이해하기 쉽고, 리팩터링과 유지보수가 수월할 뿐만 아니라 논리적으로 정연하다.

SOLID는 객체 지향 4대 특성을 발판으로 하고 있으며, 디자인 패턴의 뼈대이며 스프링 프레임워크의 근간이기도 하다.

 

 

디자인 패턴

어댑터 패턴(Adapter Pattern)

프록시 패턴(Proxy Pattern)

데코레이터 패턴(Decorator Pattern)

싱글턴 패턴(Singleton Pattern)

템플릿 메서드 패턴(Template Method Pattern)

팩터리 메서드 패턴(Factory Method Pattern)

전략 패턴(Strategy Pattern)

템플릿 콜백 패턴(Template Callback Pattern)

 

 

Spring Triangle(IoC/DI, AOP, PSA)

제어의 역전(IoC: Inversion of Control) / 의존성 주입(DI: Dependency Injection)

관점 지향 프로그래밍 : AOP(Aspect-Oriented Programming)

일관성 있는 서비스 추상화 : PSA(Portable Service Abstraction)

 

 

Java 8 : Lambda

 

 

 

 


참고

 

스프링 입문을 위한 자바 객체 지향의 원리와 이해

자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량 애플리케이션 프레임워크인 스프링은 자바와 객체 지향이라는 기반 위에 굳건히 세워져 있다. 따라서 스프링을 제대로 이해하고 활용

www.yes24.com

 

객체 지향 원리와 이해

목차

www.notion.so

 

반응형