[워밍업클럽3기] Backend 1주차 발자국
Section 02. 추상추상: 뽑을 추 & 코끼리 상(형상 상)구체적 정보에서 어떠한 이미지를 뽑아냄wiki정의 : 사물을 정확하게 이해하기 위해서 사물이 지니고 있는 여러가지 측면 가운데서 특정한 측면만을 가려내어 포착하는 것이다. 어떤 일면만을 추상하는 것은 다른 측면을 버린다는 것과 같다.추상은 항상 구체적인 실재에서 시작해야한다..추상화 과정.. 빅뱅이론에서 쉘든은 추상화가 덜되었고, 보통사람은 추상화가 잘된느낌??추상화가 덜되어서 자꾸 뭐든 설명하려들고, 나머지사람들은 추상화가 잘되어 그렇게까지 디테일하게 말하지 않는 느낌? 예시) 추상: 너 만나기 전에 배가 고파서 먼저 밥먹었는데, 너는 밥 먹었니? 구제: 너와 00시에 만나기로 하였는데, 00시부터 나의 위에서 아무것도 없기 때문에 내 뇌로 배고프다는 신호를 보내주었기 때문에 나의 뇌가 무언가를 먹어야 한다는 신호를 보내어 집안의 냉장도를 열어서 음식을 찾아서 내 입에서 저작작용을 거쳐 식도를 지나 위로 넘어가는 일(=밥먹음)을 하고 왔는데, 너도 그런 일(=너도 먹음?)을 하고 왔니?추상: 심플, 구제: 구구절절 ?추상: 핵심만 담아 짧고 간결하게 표현하는 것. (효율 극대화)구제: 하나하나 풀어서 최대한 자세하게 설명하는 것. (비효율적)Method: 두개이상의 일을 하지 않도록 노력할 것!! 생략할 정보와 의미를 부여하고 드러낼 정보 구분해야함반환 타입 매서드명 (파라미터) {매서드구현부}<method name: 매서드명>추상화된 구체를 유추할 수 있는, 적절한 의미가 담긴 이름파라미터와 연결지어 더 풍부한 의미를 전달 할 수도 있음.<Parameter: 파라미터>파라미터의 타입, 개수, 순서를 통해 의미 전달외부세계와 소통하는 창임!외부세계로 method를 작성한 사람이 읽는 사람, 사용하는 사람으로 하여금 내가 뭘 할지 보여주는 것.<반환타입>method signature에 납득이 가는, 적절한 타입의 반환값 돌려주기.반환타입이 boolean의 경우 참거짓임.void 대신 충분히 반환할 만한 값이 있는지 생각해 볼것.반환값이 있다면 테스트가 용이해짐.void = 반환값이 없음을 의미. "값을 반환하지 않는다"의 의미.추상화는 코드의 양이 중요하다기 보다는 의미가 중요함!!! Section 03. 논리, 사고의 흐름사고의 depth 줄이기보이는 depth를 줄이는 것이 아니라 "사고과정의 depth"를 줄이는 것이 중요함.사고과정에 도움이 되면 여러 depth가 있어도 굳이 분리할 필요 없음 선언한 변수와 실제 사용되는 코드 사이에 쓸데없는(=연관되어있지 않은) 코드를 많이 넣지말것쉽게 생각해서 친한친구끼리 붙여두는것. 친한 친구 두명사이에 여러명이 있으면 둘의 대화가 하기 힘들어짐. 공백라인: 라인의 공백을 잘 주면 코드 읽기가 쉬워짐아무거나 붙여놓고, 떨어뜨려놓으면 가독성이 떨어지기 때문에, 의미단위로 자르는 것이 좋음 부정어: 최대한 부정서 사용을 자제할 것.부정의 의미를 담은 다른 단어 유무 확인부정연산자는 가독성이 떨어지기 때문. Section 04. 객체 지향 패러다임추상의 관점으로 보는 객체지향 절차지향: 정해진 순서대로(절차) 처리 객체지향: 객체간의 협력 함수형: 순수함수를 기반으로함.관심사의 분리관심사를 모음 = 유지보수가 쉬워짐높은 응집도 = 낮은 결합도 객체 설계객체가 제공하는것절차지향에서 잘 보이지 않았던 개념을 가시화함관심사 모음캡슐화되어 높은 추상화레벨에서 domain logic을 다룰 수 있음새로운 객체를 만들때 주의할점1개의 관심사인가외부세계와 어떠한 소통을 하려는지 생각할 것생성자, 정적 factory method에서 유효성 검증가능domain에 특화된 검증 로직이 들어갈 수 있음setter and getter 사용자제데이터는 불변이 최고임변하는 데이터라도 객체가 handling할 수 있어야함.객체 내부에서 자체적으로 변경/ 가공으로 처리 할 수 있는가네이밍은 의도를 드러내는 네이밍이 중요함field의 수는 적을 수록 좋음불필요한 데이터가 많다 = 복잡도가 높다 = 대응할 변화가 많다 = 코드가 골치아파진다미리 제공하는 것이 성능상의 이점이 있다 = 필드로 가지고 있는 것이 좋을 수 있음.SOILDSRP: Single Responsibility Principle하나의 클라스 = 하나의 변경이유(= 책임)객체가 가진 공개 메서드, 필드, 상수 등은 해당 객체의 단일 책임에 의해서만 변경됨관심사의 분리높은 응집도, 낮은 결합도SRP를 잘지킴 = 겹합도 낮음 = individual workingOCP: Open-Closed Principle개방-폐쇄 원칙확장(=open)과 수정(=closed)즉, 확장은 가능, 수정은 불가능추상화와 다형성을 활용하여 지킬 수 있음.LSP: Liskov Substitution Principleparent class의 instance는 child-class의 instance로 치환가능자식클라스는 부모클라스기능 +aLSP를 위반하면 상속 클라스를 사용할 때 오동작, 예상밖의 예외가 발생하거나 이를 방지하기 위하여 불필요한 타입체크가 동반될 수 있음.ISP: Interface Segregation Principle클라이언트는 사용하지 않는 인터페이스에 의존하면 안됨interface를 잘게 쪼개기!ISP위반 = 불필요한 의존성 = 결합도 높아짐 = 특정 기능의 변경이 여러 클래스에 영향을 미침DIP: Dependency Inversion Principle상위수준의 모듈은 하위 수준모듈에 의존해서는 안됨둘 모두 추상화에 의존의존성의 순방향은 고수준이 저수준 모델을 참조하는것, 역방향은 고수준 저수준 모두 추상화에 의존하는것직접적으로 의존하지 않게 설계됨. Section 05. 객체 지향 적용하기상속과 조합상속 < 조합상속은 수정이 어려움조합 and interface를 활용하는 것이 유연한 구조임상속을 통한 코드의 중복제제가 주는 이점보다, 중복이 생겨도 유연한 구조가 주는 설계적 이점이 더 큼.즉 중복도 상황보며 잘 이용해야함 중복이 무조건 나쁜건 아님Value Object (VO)식별자 없이 내부의 모든 값이 다 같아야 동등한 객체로 취급함. 개념적으로 전체 필드가 다같이 식별자 역할을 한다고 생각해도됨\ 기본 타입을 객체로 감싸서 추상화 값으로 취급하기 위해서 불변성, 동등성, 유효성 검증등을 보장해야함.불변성: final field, setter금지동등성: 서로다른 인스턴스여도(동일성이 달라도), 내부의 값이 같이면 같은 값 객체로 취급유효성 검증: 객체가 생성되는 시점에 값에 대한 유효성을 보장하기.Entity식별자가 같음 = 동등한 객체같은 식별자, 필드의 값이 다른 두 인스턴스 = entity가 시간이 지남에 따라 변화할 것으로 예측가능일급 컬렉션일급: 다른 요소에게 가능한 모든 연산자를 지원하는 요소변수할당가능파라미터 전달가능함수의 결과로 반환 가능 일급함수: 함수는 변수에 할당될 수 있고, 인자로 전달가능, 함수의 결과로 함수가 반환될 수 있음일급 컬렉션: 컬렉션만을 유일하게 필드로 가지는 객체다른 객체와 동등한 레벨로 다루기 위함collection 추상화: 의미담을 수 있고, 가공로직의 보금자리가 생기고 테스트 작성도 가능 Enum 특성: 상수의 집함, 상수와 관련된 로직을 담을 수 있는 공간특정 도메인 개념에 대해 그 종류와 기능 표현가능변정이 잦은 개념= DB로 관리하는 것이 나을 수 있음다형성활용변화하는것 : 조건 & 행위 = 구체변화하지 않는것: 조건을 만족하는가? 행위를 수행하는가? = 추상화OCP를 지키기 위해서 a,b는 구별해야함.숨겨져 있는 도메인 개념 도출도메인 지식은 만드는 것이아니라 발견하는것!!!객체지향 = 흉내내는 도구설계할 때는 근시적, 거시적 관점에 따라 최대한 미래를 예측틀렸다는 것을 인지할 경우 돌아올 수 있도록 코드를 짜야함. Day02.미션추상: 핵심만 담아 짧고 간결하게 표현하는 것. (효율 극대화) 구체: 하나하나 풀어서 최대한 자세하게 설명하는 것. (비효율적) 예시) 추상: 너 만나기 전에 배가 고파서 먼저 밥먹었는데, 너는 밥 먹었니? 구체: 너와 00시에 만나기로 하였는데, 00시부터 나의 위에 아무것도 없었기 때문에, 내 뇌로 배고프다는 신호를 보낸 결과 나의 뇌가 무언가를 먹어야 한다는 신호를 보내어 집안의 냉장고에서 찾은 음식이 내 입에서 저작작용을 거쳐 식도를 지나 위로 넘어가는 일을 하고 왔는데, 너도 그런 일을 하고 왔니? 즉, 보통 사람이 이야기하는 것은 추상화 된 개념이고, 이를 하기 위한 코딩을 하는 것이 구체가 되는 것이 아닐까 생각하게 되었습니다. Josh Darnit 유튜버의 Exact instructions challenge영상에서 아빠는 구체화 된 상태이고 아이들이 추상화 된 방법으로 이야기하는 것이라 생각하게 되었습니다. Day04. 미션 // ; Original public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }//ordering public boolean validateOrder(Order order) { if (order.getItems().isEmpty()) { log.info("주문 항목이 없습니다."); return false; } if (order.getTotalPrice() <= 0) { log.info("올바르지 않은 총 가격입니다."); return false; } if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } return true; }// 캡슐화 public class Order { public boolean isValid() { return !getItems().isEmpty() && getTotalPrice() > 0 && hasCustomerInfo(); } public String getValidaionMessage { if(getItems().isEmpty()) return "No order list"; if(getTotalPrice() <= 0) return "Wrong Price"; if(!hasCustomerInfo()) return "No user information"; return "Thanks for order." } }// 부정문 제거 public class Order { public boolean isValid() { return hasItems() && getTotalPrice() > 0 && hasCustomerInfo(); } public String getValidationMessage() { if(!hasItems()) return "No order list"; if(getTotalPrice() <= 0) return "Wrong Price"; if(!hasCustomerInfo()) return "No user information"; return "Thanks for order." } public boolean hasItems() { return !getItems().isEmpty(); } public boolean getTotalPrice() { return totalPrice; } public boolean hasCustomerInfo() { return customerInfo() != null; } } SRP: Single Responsibility Principle 하나의 클래스, 하나의 책임 예시) 필름카메라: 필름카메라는 카메라라는 목적에 맞게 사진을 찍는 하나의 기능만을 가지고 있음. OCP: Open-Closed Principle 확장에 대해 열려있고, 수정에 닫혀있음. 예시) 디지털 카메라: 사진을 찍는 목적은 있지만, 여러 렌즈를 교체하며 zoom정도의차이(확장)의 기능을 가지고 있지만, 사진 자체를 수정할 수는 없음. LSP: Liskov Substitution Principle 자식 클라스는 부모 클라스를 대체할 수 있어야 한다. 예시) 스마트폰에 대해 이야기 할 수 있음. 초창기 핸드폰(부모클라스)의 경우 전화와 문자의 기본적인 기능만 있었으나 현재의 스마트폰(자식클라스)는 거기에 추가적으로 카메라, 인터넷접속등의 추가적인 기능이 있어 자식이 부모 클라스를 대체할 수 있다. ISP: Interface segregation Principle 하나의 커다란 인터페이스보다 작고 구체적인 인터페이스가 좋다. 예시) 카메라 기능: 실제 카메라는 사진을 찍는 기술을 가지고 있고, 그 사진을 편집하는 다른 프로그램이 동시에 존재한다. 이 두개를 모두 할 수 있는 것이 스마트폰인데, 이마저도 스마트 폰안의 다른 작은 인터페이스가 구체적이기 때문에 가능한것이다. DIP: Dependency Inversion Principle 고수준 모듈은 저수준 모듈에 의존해서는 안되고, 둘다 추상화된 인터페이스에 의존해야함. 예시) C type의 충전선은 여러 기기를 충전할 수 있음. C type 충전 cable로아이폰, 아이패드, 노트북 모두 충전이 가능함. 즉 추상화된 인터페이스(C type cable)에 각각의 인터페이스(아이폰, 아이패드, 갤럭시, 노트북등)는 각자 구현하는 것임. 마치며...3개 스터디를 한번에 하려는건 역시 무모한 일인가싶어 우선순위를 정했다.FE는 물론 중요하지만 코딩에 시간을 생각보다 많이 써야해서 내 배움 속도에 맞게 하기로 하였다.그래서 BE-CS-FE 순으로 초점을 두기로 하였다. BE야말로 내가 잘 모르는 분야인데 와 Java로 하려니 더 머리가 복잡쓰하다그래도 C#을 배웠던 짬바덕일까, 생각보다 코드 부분에서 나쁘지 않았다.그래도 개념적인 부분에 많은 것이 부족하다 느꼈기 때문에 그런 부분을 다시 review할 수 있는 것이 너무 좋음.특히, solid라는 개념은 대충알고 있었는데 다시한번 짚을 수 있어서 너무 좋음.아 뭐 이런거는 이렇겠지 싶었던 부분도 다시집고 넘어 갈 수 있어서 너무 좋지만 남은 3주가 너무 걱정됨.내가 왜 세개를 했냐고 이렇게 안하면 난 안할테니까...이번주 고생한 나에게 상따윈 없다 담주 더 고생해라!