SOPT 1차 세미나 후 회고 생각 정리

Polla·2023년 5월 12일
0

SOPT

목록 보기
2/2
post-thumbnail

SOPT 1차 세미나 회고록


`SOPT`에 들어온 이후 `git`과 노션에만 신경을 쓰느라
`velog` 에는 잘 정리를 못한 것 같아서 작성하는 세미나 회고록...
대부분 진행하면서 궁금했던 부분을 생각의 흐름대로 정리해놨습니다!

우선 나는 SOPT를 들어오면서 자바에 대해 처음 배우게 되었다.
그러다 보니 JAVA하면 나오는 객체지향이란 무엇일까?


1. OOP (객체지향 프로그래밍)


OOP란 Object Oriented Programming 의 약자입니다.

객체란?

우선 객체 지향에서 '객체' 즉, Object란 무엇일까?

자바 공식 문서에서는 Object

they too consist of state and related behavior. An object stores its state in fields (variables in some programming languages) and exposes its behavior through methods (functions in some programming languages). Methods operate on an object's internal state and serve as the primary mechanism for object-to-object communication. Hiding internal state and requiring all interaction to be performed through an object's methods is known as data encapsulation — a fundamental principle of object-oriented programming.

라고 설명하고 있다. 기본적으로 많이 들어봤던, 현실 객체를 기반으로 한
상태를 저장하고 메서드를 통해 동작을 노출하는 개체라고 설명이 되어있었다.

정답은 없겠지만 공식 문서로는 아직 완전히 왜? 객체지향일까? 왜 사용할까?
에 대한 물음의 답변을 얻지 못했다고 판단했다.

객체지향의 사실과 오해

책 홍보 아닙니다..
주변으로부터 해당 책 추천을 많이 받았기 때문에 해당 책으로 객체지향에 대한 개념을 좀 잡고 싶었다.

물론 책 한권만 읽고 뚝딱 객체지향에 대한 개념이 잡히진 않지만,
나는 당시에 책과 SOPT에서의 세미나를 병행하고 코드를 치면서 개념을 잡을 수 있었던 것 같다.

그러니 나는 코드를 꼭 같이 치면서
왜 이렇게 작성하는지에 대한 생각을 해보는 기회를 가지면 좋을 것 같다.
지금은 자바가 넘우 좋아요.


2. SOLID 원칙



SOLID는 사실 SOPT에 들어오기 전, 면접을 보기 위해 공부한
자바에 관한 지식들 중 하나였다.

워낙 자바에 관한 지식을 찾아볼때 많이 나오는 원칙이기에 자바에만 국한된다고 생각할 수 있지만(그것은 나)

사실 이 원칙은 로버트 C. 마틴에 의해 작성된 Clean Code 에서 명명한 객체지향 프로그래밍 및 설계의 기본 원칙이다


SRP(Single Responsibility Principle)OCP(Open Closed Principle)
단일 책임 원칙개방 폐쇄 원칙

LSP(Liskov Substitution Principle)ISP(Interface Segregation Principle)DIP(Dependency Inversion Principle)
리스코프 치환 원칙인터페이스 분리 원칙의존 역전 원칙



2-1. SPR 단일 책임 원칙


모듈이 변화하는 이유는 한가지 여야 한다.

가끔 이 원칙은 모듈은 한가지 일만 해야한다.라고 해석이 되는것 같은데
찾아보니 "A module should have one reason to change"가 정확하다.

사실 객체지향을 공부하면서 가장 어려웠던 부분이었다.
변화할수도 있는것 아닌가?


우선 가장 큰 문제는 소스충돌과 중복 이라고 생각한다.
class Post {

  getTitle() { ... }
   
  getPost() { ... }
     
  deletePost() { ... }
}

위와 같은 코드가 있다고 가정했을때,
deletePost의 경우 Database와 연결이 되어있고, getTitle의 경우에는
Post entity와 연결이 되어있기 때문에 하나의 액터만 책임지고 있다고 할 수 없다.

2-2. OCP 개방-폐쇄 원칙


소프트웨어는 확장을 위해 열려있어야 하지만, 수정에는 닫혀있어야 한다.


바로 예제로 들어가 생각했을때,

 class Post {
  
    if (category.equals("Notice")) {
        this.title = "[공지]" + title;
  
    } else if (category.equals("Horror")) {
        this.title = "[공포]" + title;
    }

만약 카테고리에 따라서 title에 해당하는 카테고리를 붙여야 한다고 가정했을때
새로운 카테고리를 생성할때마다 Class를 변경해주는 것
수정에 열려있다고 할 수 있기에 이를


class Notice extends Post {
 {
    this.title = '[공지]' + title;
    this.category = 'Notice'
  }
}

class Horror extends Post {
 {
    this.title = '[공포]' + title;
    this.category = 'Horror'
  }

extend를 사용해 Class를 확장시켜 준다면
OCP 원칙을 지킨 설계라고 할 수 있게 된다고 생각했습니다.

2-3. LSP 리스코프 치환 원칙


프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.


리스코프 치환 원칙 같은 경우는 직사각형과 정사각형 그리고 동물의 분류가 가장 많은 예시로 볼 수 있었다.


예를 들어
  public class Rectangle{
  ...
    public void setHeight(int height)
    {
        this.height = height;
    }
    
    public int getArea()
    {
        return width * height;
    }
  ...
  }

흔히 수학에서 정사각형은 직사각형에 포함이 되기 때문에,
이를 @Override 하여

public class Square extends Rectangle  {
  ..
  	@Override
    public void setWidth(int width){
  
    	super.setWidth(width);
        super.setHeight(width);
  
    }
  
    @Override
    public void setHeight(int height){
  
    	super.setWidth(height);
    	super.setHeight(height);
  
	}
 }

와 같이 작성한다고 가정했을때,
LSP원칙에 적합하다면 Square Class 에서 (5, 10) 을 넣었을 때의 결과와
Rectangle Class에서 (5,10)을 넣었을 때의 결과가 같아야 합니다.

하지만 역시 직사각형은 하위타입인 정사각형 클래스가 부모 클래스인 직사각형 클래스를 위반하기 때문에
이 코드는 LSP를 따른다고 할 수 없습니다.

반대로 Animal Class를 생성하고

  abstract class Animal{}
  
  interface walk{
  	void walk();
  }
  
  interface swim{
  	void swim();
  }
  
  class Dog extends Animal implements walk {
    public void walk() {
        System.out.println("강아지가 걷습니다.");
    }
  
  class Fish extends Animal implements swim {
  	public void swim(){
  		System.out.println("물고기가 수영합니다.")
  }
}

로 작성한다면,
부모클래스에 위배되지 않으면서 의도와 다른 오버라이딩을 하지 않았기
때문에 LSP에 위배되지 않는다고 할 수 있습니다.


2-4. ISP 인터페이스 분리 원칙


특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.

개인적으로 이 원칙은 SPR과 결과가 인터페이스 분리라는 점에서
비슷하게 와닿는다고 생각한다. (개인적인 생각)

둘의 차이점을 생각해보자면,
SPR은 책임에 의해 그 클래스 나누지만, ISP는 인터페이스를 범용성 좋게 나눈다는 부분이 된다고 생각한다.

예를 들어,

interface Sopt{
  
	void appJam()
  	void sopkerton()
  	void seminar()
  	void event()
  
 }

Sopt 동아리에 회원이 되어, 위와 같은 활동을 한다고 생각했을때,
( 급 SOPT 자랑..)
appJamsopkerton은 활동하지 않고 있는 회원도 참여가 가능하지만

seminarevent는 참여가 불가능 하기 때문에,
만약 비활동 회원이 이라면 참여가 불가능함에도 이 메서드를 구현해야 하게 됩니다.

만약 이를

interface YbSopt{
 	void seminar()
 	void event()
}
  
interface Sopt{
	void sopkaton()
  	void appJam()
}

으로 작성한다면 비활동 회원은 불필요한 메서드를
구현하지 않아도 되기
때문에 이것이 LSP를 지켰다고 할 수 있게 된다고 생각한다.


2-4. DIP 의존 역전 원칙


추상화된 것은 구체적인 것에 의존하면 안된다. 구체적인 것이 추상화된 것에 의존해야 한다.


구체적인 것이 무엇이고, 추상화 된 것이 무엇인지
애매하게 느껴지는 부분들이 있지만, 개인적으로 나는

상위클래스에서 하위 클래스 인스턴스를 생성하여 사용하는 것이 아닌, 상위의 인터페이스 타입의 객체를 만들어 의존하라는 말이 좀 더 와닿았다.

위에 동물이라는 말이 나왔으니 하는 말이지만,

예를 들어 Animal이라는 상위 클래스를 진돗개, 포메라니안 같이 개의 범주 안에 들어가는 구체적인 것이 들어간다면 dog 라는
인터페이스 타입의 객체를 만들어 둔다는 쪽으로 생각 할 수 있지 않나...라고 생각한다.


사실 더 쓸게 많은데 MVC 패턴 같은 경우는
이 한페이지에 넣기 힘들어서 다음페이지에다가 정리해두기..!

profile
트러블 슈팅 Blog => https://polla.palms.blog/home

0개의 댓글