최범균님의 인프런 강의를 학습한 내용을 기록했습니다.
클래스나 메서드가 커지면 절차 지향의 문제 발생
큰 클래스 : 많은 필드를 많은 메서드가 공유
큰 메서드 : 많은 변수를 많은 코드가 공유
여러 기능이 한 클래스/메서드에 섞여 있을 가능성
책임에 따라 알맞게 코드 분리 필요
전형적인 역활 분리를 사용한다.
ex)
간단한 웹
간단한 웹의 경우 컨트롤러, 서비스, DAO의 계층 분리 방식을 사용할 수 있다.
복잡한 도메인
도메인이 복잡하다면 모델을 Entity, Value, Repository, Domain Service로 분리하여 사용할 수 있다.
AOP
여러 기능에 공통으로 포함된 기능은 Aspect를 사용해서 분리할 수 있다.
GoF
디자인 패턴을 사용해서 여러 기능을 분리할 수 있다.
포인트를 계산하는 부분을 별도의 클래스로 사용
네트워크, 메시징, 파일 등 연동 처리 코드 분리
연속적인 if-else는 추상화 고민
역활 분리가 잘 되면 테스트가 용이해진다.
해당 코드는 평문 암호화하고 암호문을 담아 외부에 요청하고 응답을 다시 복호화한다.
public class CashClient {
private SecretKeySpec ketSpec;
private IvParameterSpec ivSpec;
private Res post(Req req) {
String reqBody = toJson(req);
//암호화 수행
Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
String encReqBody = new String(Base64.getEncoder().encode(cipher.doFinal(reqBody)));
//암호문 전송
ResponseEntity<String> responseEntity = restTemplate.postForEntity(api, encReqBody, String.class);
String encRespBody = responseEntity.getBody();
//복호화 수행
Cipher cipher2 = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
String encReqBody = new String(cipher.doFinal(Base64.getDecoder().decode(encRespBody)));
return jsonToObj(respBody);
}
}
해당 코드의 기능과 책임을 분리하기 위해 계산 분리, 외부 연동 분리 방법을 적용할 수 있다. 이제 코드를 분리해보자!
public class Cryptor {
private SecretKeySpec keySpec;
private IvParameterSpec ivSpec;
//암호화
public String encrypt(String plain) {
Cipher cipher = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
return new String(Base64.getEncoder().encode(cipher.doFinal(plain)));
}
//복호화
public String decrypt(String encrypted) {
Cipher cipher2 = Cipher.getInstance(DEFAULT_TRANSFORM);
cipher2.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
return new String(cipher.doFinal(Base64.getDecoder().decode(encrypted)));
}
}
계산 기능(암호화, 복호화)은 Cryptor 클래스가 담당하며 CashClient에서 조립해서 사용하면된다.
조립해보자!
public class CashClient {
private Cryptor cryptor;
private Res post(Req req) {
String reqBody = toJson(req);
//암호화 수행
String encReqBody = cryptor.encrypt(reqBody)
//암호문 전송
ResponseEntity<String> responseEntity = restTemplate.postForEntity(api, encReqBody, String.class);
String encRespBody = responseEntity.getBody();
//복호화 수행
String respBody = cryptor.decrypt(encRespBody)
return jsonToObj(respBody);
}
}
위 코드의 조건 분기를 추상화 해보자!
Movie 클래스를 추상 클래스로 변경하고 각 하위 클래스가 포인트 기능을 제공하도록 변경한다.
덕분에 좋은 내용 잘 보고 갑니다.
정말 감사합니다.