프로그래밍 패러다임 - 객체지향 프로그래밍

ROCKBELL·2022년 11월 18일
0

CS 전공지식

목록 보기
6/18

객체지향 프로그래밍

객체들의 집합으로 프로그램의 상호작용을 표현하며 데이터를 객체로 취급하여 객체 내부에 선언된 메서드를 활용한 방식입니다

객체지향 프로그래밍의 특징

추상화(abstraction)

복잡한 시스템으로부터 핵심적인 개념 또는 기능을 간추려낸 것을 말합니다

캡슐화(encapsulation)

객체의 속성과 메서드를 하나로 묶고, 외부로부터 은닉화 한 것을 말합니다

상속(inheritance)

상위 클래스의 특성을 하위 클래스가 이어받아서 재사용하거나 확장하는 것을 말합니다

다형성(polymorphism)

하나의 메서드나 클래스가 다양한 방법으로 동작하는 것을 말합니다

오버로딩 (정적 다형성 - 컴파일단계)

오버로딩(overloading)은 같은 이름을 가진 메서드를 여러개 정의하는 것을 말합니다
동일한 이름의 메서드에 argument를 다르게 적용하여 구현할 수 있습니다
자바 등에서 구현가능하며, 자바스크립트에서는 동일한 이름의 메서드를 정의할 수 없습니다. 다만, 자바스크립트는 argument를 배열로 가져올 수 있기때문에 오버로딩이 필요 없습니다

오버라이딩 (동적 다형성 - 런타임단계)

오버라이딩(overriding)은 상위 클래스에서 상속받은 메서드를 하위 클래스에서 재정의하는 것을 말합니다

SOLID 설계원칙

단일책임원칙 (SRP, Single Responsiblity Principle)

모든 클래스는 각각 하나의 책임만을 가져야하는 원칙.
예를들어 A라는 로직을 수정한다면 클래스는 A에 관련된 수정만 해야됩니다

  • 잘못된 예시
class Employee {
	constructor(name, position){
		this.name = name;
        this.position = position;
	}
    calculateExtraHour(){ // 초과 근무시간을 계산하는 메서드
    
    }
    calculatePay(){ // 급여를 계산하는 메서드
    	this.calculateExtraHour();
    }
    reportHours(){ // 근무시간을 계산하는 메서드
    	this.calculateExtraHour();
    }
    save(){ // 변경된 정보를 DB에 저장하는 메서드
    	
    }
}

해당 로직에 의하면 급여를 계산하는 로직이 변경되면, calculatePay() 코드를 수정합니다. 또한 근무시간을 계산하는 로직이 변경되면, reportHours()의 코드도 수정합니다. 두개의 메서드는 calculateExtraHour() 메서드를 공유하기때문에 의도치 않게 영향을 주게됩니다. calculatePay() 메서드로 인해 이미 변경된 내용으로 reportHours()로 넘어가기때문에 잘못된 정보가 전달 되는 것입니다
이러한문제를 해결하기위한 방법으로 퍼사드패턴(Facade Pattern)이 있습니다

  • 올바른 예시 (퍼사드 패턴)
class EmployeeFacade {
	constructor(name, positon) {
    	this.name = name;
        this.position = position;
    }
    
    calculatePay(){ // 급여를 계산하는 메서드
    	return new PayCalculator().calculatePay();
    }
    
    reportHours(){ // 근무시간을 계산하는 메서드
    	return new HourReporter().reportHours();
    }
    
    save(){ // 변경된 정보를 DB에 저장하는 메서드
    	return new EmployeeSaver().save();
  	}
}

class PayCalculator() {
	calculateExtraHour(){ // 초과 근무시간을 계산하는 메서드
    
    }
    
	calculatePay() {
    	this.calculateExtraHour();
    }
}

class HourReporter () {
	calculateExtraHour(){ // 초과 근무시간을 계산하는 메서드
    
    }
    
	reportHours() {
    	this.reportHours();
    }
}

class EmployeeSaver  () {
	calculateExtraHour(){ // 초과 근무시간을 계산하는 메서드
    
    }
    
	save() {
    
    }
}

이렇게 구현하면 변경사항이 생겨도 각각의 구현 클래스를 변경하면 되기때문에, EmployeeFacade 클래스는 변경이 생기지 않습니다. 각각의 구현 클래스도 하나의 책임(액터)만 담당하기때문에 서로에게 전혀 영향을 주지 않습니다.

참초 URL - https://wookgu.tistory.com/28

개방-폐쇄 원칙(OCP,Open Colosed Principle)

유지보수사항이 생겼을 때 쉽게 확장(Open)은 가능해야하지만, 기존 코드의 수정은 되도록 변경하지 않아야 한다는 원칙

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

부모 자식 클래스가 서로 바뀌어도 문제없이 시스템이 실행되야 한다는 원칙.
즉, 자식 객체의 확장이 부모 객체의 방향을 온전히 따라야 한다는 원칙입니다

인터페이스 분리 원칙(ISP, Interface Sergregation Principle)

하나의 일반적인 인터페이스보다 구체적인 여러개의 인터페이스를 만들어야한다는 원칙
보편적인 기능만 메서드로 공통으로 상속받고, 각각의 기능들은 interface로 구현하고 implements 로 필요한 기능만 상속받으면 되도록 구현하면 됩니다.

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

고수준(추상회된 엔터페이스나 상위 클래스)의 모듈에 의존해야한다는 원칙.
변하기 쉬운 것에 영향받지 않고 상위클래스는 하위클래스의 변화로부터 독립적으로 구현되어야합니다

profile
luv it

0개의 댓글