반응형 All205 [Clean Architecture] 3. 설계원칙 - (2) SRP (단일 책임 원칙) 역사적으로 SRP는 아래와 같이 기술되어 왔습니다 단일 모듈은 변경의 이유가 하나, 오직 하나뿐이어야 한다 SRP를 정의는 아래처럼 말할 수 있습니다 하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다 (액터 : 해당 변경을 요청하는 한 명 이상의 사람들) (모듈: 소스파일) 징후 1 : 우발적 중복 Employee 클래스에 calculatePay(), reportHours(), save() 메소드를 가집니다 CFO, COO, CTO가 모두 이 클래스의 메소드를 사용합니다 현재 이 클래스는 SRP를 위반합니다 이 3가지 메서드가 서로 매우 다른 세 명의 액터를 책임지기 때문입니다 calculatePay()는 회계팀에서 기능을 정의하며, CFO 보고를 위해 사용합니다 reportHours().. 2021. 9. 12. [Clean Architecture] 3. 설계원칙 - (1) SOLID? 좋은 아키텍처를 정의하는 원칙은 SOLID 입니다 좋은 소프트웨어 시스템은 깔끔한 코드로부터 시작합니다 좋은 벽돌을 사용하지 않으면 빌딩 아키텍처가 좋고 나쁨은 그리 큰 의미가 없습니다 반대로 좋은 벽돌로 빌딩 아키텍처를 엉망으로 만들 수 있습니다 좋은 벽돌로 좋은 아키텍처를 정의하는 원칙은 SOLID 입니다 SOLID 원칙은 함수와 데이터 구조를 클래스로 배치하는 방법, 그리고 이들 클래스를 서로 결합하는 방법을 설명해줍니다 SOLID 원칙의 목적은 중간 수준의 소프트웨어 구조가 아래와 같도록 만드는데 있습니다 (중간 수준 : 프로그래머가 이들 원칙을 모듈 수준에서 작업할 때 적용할 수 있다는 뜻) 변경에 유연하다 이해하기 쉽다 많은 소프트웨어 시스템에 사용될 수 있는 컴포넌트 기반이 된다 SOLID .. 2021. 9. 5. [엘레강트 오브젝트] 2. 학습 - (3) 항상 인터페이스를 사용하세요 객체들은 서로 필요로 하기 때문에 결합됩니다 애플리케이션이 성장하기 시작하고 객체 수가 수십 개가 넘어가면서부터 객체 사이의 강한 결합도가 심각한 문제가 됩니다 결합도 문제는 유지보수성에 큰 영향을 미칩니다 애플리케이션 전체를 유지보수 가능하도록 만들기 위해서는 최선을 다해서 객체를 분리해야합니다 객체 분리란 상호작용하는 다른 객체를 수정하지 않고도 해당 객체를 수정할 수 있도록 만든다는 것을 의미합니다 바로 인터페이스를 이용하는 것입니다 interface Cash { Cash multiply(float factor); } Cash는 인터페이스 입니다 우리의 객체가 다른 객체와 소통하기 위해 따라야하는 계약입니다 class DefaultCash implements Cash { private int dol.. 2021. 9. 5. [엘레강트 오브젝트] 2. 학습 - (2) 최소한 뭔가는 캡슐화하세요 너무 많이 캡슐화하는 방식도 좋지 않지만, 아무것도 캡슐화하지 않는 방식 또한 바람직하지 않습니다 class Year { int read() { return System.currentTimeMillis() / / (1000 * 60 * 60 * 24 * 30 * 12) - 1970; } } Year 클래스의 인스턴스는 어떤 것도 캡슐화하지 않기 때문에 이 클래스의 모든 객체들은 동일합니다 이렇게 아무것도 캡슐화하지 않는 방식은 바람직하지 않습니다 이처럼 프로퍼티가 없는 클래스는 객체지향 프로그로밍에서 악명 높은 정적 메서드와 유사합니다 아무런 상태, 식별자도 가지지 않고 오직 행동만을 포함합니다 인스턴스 생성과 실행을 엄격하게 분리하는 순수한 OOP에서는 기술적으로 프로퍼티가 없는 클래스를 만들 수 없습.. 2021. 9. 5. [엘레강트 오브젝트] 2. 학습 - (1) 가능하면 적게 캡슐화하세요 모든 것은 유지보수성과 관련이 있습니다 복잡성이 높을수록 유지보수성이 저하되고, 시간과 돈이 낭비되며, 고객 만족도가 떨어집니다 따라서 4개 또는 그 이하의 객체를 캡슐화할 것을 권장합니다 내부에 캡슐화된 객체 전체를 가리켜 객체의 상태 또는 식별자라고 부릅니다 class Cash { private Integer digits; private Integer cents; private String currency; } Cash 클래스는 3개의 객체를 캡슐화하고 있습니다 이 3개의 객체들이 함께 모여 Cash 클래스 객체를 식별합니다 동일한 값의 달러, 센터, 통화를 가진 2개의 객체가 있다고 하면 두 객체는 서로 동일할까요? 아닙니다. Java 언어가 안고 있는 설계적 결함때문에 같지 않습니다 Java를 비.. 2021. 9. 4. [엘레강트 오브젝트] 1. 출생 - (3) 생성자에 코드를 넣지 마세요 인자에 손대지 말자 class Cash { private int dollars; Cash(String dlr) { this.dollars = Integer.parsInt(dlr); } } 인자를 정수로 표현할 필요는 있지만, 생성자 내 객체 초기화에는 코드가 없어야 하고 인자를 건드려서는 안됩니다 대신, 필요하다면 인자들을 다른 타입의 객체로 감싸거나 가공하지 않은 형식으로 캡슐화해야 합니다 class Cash { private Number dollars; Cash(String dlr) { this.dollars = new StringAsInteger(dlr); } } class StringAsInteger implements Number { private String source; StringAsInt.. 2021. 9. 2. [엘레강트 오브젝트] 1. 출생 - (2) 생성자 하나를 주 생성자로 만드세요 생성자는 새로운 객체에 대한 진입점입니다 몇 개의 인자를 전달받아, 어떤 일을 수행한 후, 임무를 수행할 수 있도록 객체를 준비시킵니다 class Cash { private int dollars; Cash(int dlr) { this.dollars = dlr; } } 현재 하나의 생성자가 있고, 인자로 dlr을 받아 private 변수 dollars 프로퍼티에 캡슐화합니다 이 책에서 권장하는 방식에 따라 올바르게 클래스를 설계한다면, 클래스는 많은 수의 생성자와 적은 수의 메서드를 포함할 것입니다 → 생성자의 수가 메서드의 수보다 더 많아집니다 사실 생성자의 개수가 더 많을수록 클래스는 더 개선되고, 사용자 입장에서 클래스를 더 편하게 사용할 수 있습니다 new Cash(30); new Cash(29.9.. 2021. 9. 2. 이전 1 ··· 6 7 8 9 10 11 12 ··· 30 다음 반응형