TIL - 0527

스프링

리팩토링 하기 - 관심사 분리(역할 분리)

  • 해야할 일, 언제 어떻게 변화될지 구분되는 것 : 하나의 객체는 하나의 관심사(역할, 책임)만 담당해야함
  • 다른 관심사가 하나에 모여있다면 하나의 관심사 변경이 다른 관심사 변경에 영향을 미칠 수 있기 때문에 분리해서 감추는 것이 좋음 : 사용만 하게끔
    • 변경점은 클래스 단위가 아니라 메소드에서 같은 코드를 사용하고있고, 변경이 된다면 여러 변경점이라 보면 됨 - 같은 코드를 사용하더라도 표준 방법을 사용하게 리팩토링하기
  • 독립적으로 관리하면서 필요에 의해 의존성을 주입(Dependency Injection)해주는 것임 : 필요에 따라 주입하고, 필요없으면 분리하면 됨
  • DI 방법 : 생성자, setter - 외부에서 생성(인스턴스 생성)해서 주입
    • 사용하는 쪽에서는 구체적으로 어떤 종류인지는 몰라도 그 종류의 인스턴스면 됨(다형성 이용) : DIP
    • Dao를 사용하는 클라이언트에서 서비스의 종류를 정하는 역할을 함 : ConnectionMaker 인스턴스가 어디서 만들어지는지도, 구체적으로 어떤 인스턴스인지도 신경안써도 됨
    • 클래스 사이에 관계를 맺는게 아니라 오브젝트(instance) 사이에 관계를 맺도록 해야함 : 고정적인, 특정적인 인젝션이 아니라
public class UserDao {

    private ConnectionMaker maker;

    public UserDao(ConnectionMaker maker) {
        this.maker = maker;
    }
    
    //혹은

    public void setConnectionMaker(ConnectionMaker maker) {
	    this.maker = maker;
    }    
}

public class Clent {

    public static void main(String[] args) {
        UserDao userDao = new UserDao(new nConnectionMaker());
        userDao.add(new User());
    }
}
  • 리팩토링 후 관계도

  • DB 연결방법 확장에는 열려있고, 확장에 따른 Dao의 코드 변경에는 닫혀있음
  • 인터페이스(ConnectionMaker)에 의존하고 있어서 낮은 결합도를 유지함 : 뭐가 됐든 간에 같은 방법으로 사용할 수 있다는 것만 알면 됨
  • 전략 패턴이 적용된 코드 : 전략의 컨텍스트가 UserDao이고, Connection의 방법이 전략, 전략을 선택하는게 Client, 커넥션 전략을 컨텍스트 생성자를 통해 바꿔 끼울 수 있음

스프링부트

ajax로 댓글 삭제기능 만들기

  • 클라이언트 - 서버 간의 주고 받는 데이터는 json을 사용한다
    • jackson 라이브러리에 의해 서버에서는 객체를 리턴하면 알아서 json 데이터로 변환해줌
  • 자바스크립트 ajax 요청 - 응답 코드
function answerDelete(e) {
    var form = e.parentElement;
    var req = new XMLHttpRequest();
    req.addEventListener('load', function() {
        deleteHandle(req, form.closest('article'));
    }, false);
    req.open('delete', form.action);
    req.setRequestHeader('Accept', 'application/json');
    req.send(new FormData(form));
}

function deleteHandle(req, article) {
    var data = JSON.parse(req.responseText);
    console.log(data);
    if (data.valid) {
        article.remove();
        return;
    }
    alert(data.errorMessage);
}
  • 판단은 해당 역할 객체가 함 : 삭제도, 삭제에 대한 결과 판단도
  • 컨트롤러의 종류에 따라 처리만 달리하면 됨
    • RestController : 클라이언트 사이드 랜더링이기때문에 약속된 데이터만 리턴하면 됨 - 클라이언트에서 파싱해서 랜더링
    • Controller : 서버에서 뷰 작업까지 해서 클라이언트에 넘겨줌 - 서버 사이드 랜더링
  • 클라이언트 사이드 랜더링을 위한 객체 : 약속된 플레이하기
public class Result {
    private static final Result SUCCESS = new Result(true, null);

    private boolean valid;
    private String errorMessage;

    private Result(boolean valid, String message) {
        this.valid = valid;
        this.errorMessage = message;
    }

    public static Result ok() {
        return SUCCESS;
    }

    public static Result fail(String errorMessage) {
        return new Result(false, errorMessage);
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    public boolean isValid() {
        return valid;
    }
}

리눅스

echo

  • 주어진 문자열을 표준 출력으로 출력해주는 명령어
  • 문자열을 그대로 출력해줄 수도 있지만 변수, 정해진 문자 입력 시 매칭 시켜서 그 결과를 출력할 수도 있음
    • $() : 명령어 치환
$ echo $(USER)
$ echo $(which zsh)
$ echo $(ps -ef | grep java)
$ echo *

쉘에서 쌍따옴표

  • 입력하는 문자열의 특별한 의미를 없애고 평범한 문자열로 인식하도록 함
    • 약속된 쉘의 확장을 동작하지않도록
    • $, \, `는 예외
    • 아래 두 명령어 결과로 “ “의 또다른 역할 보기 : 단어 분할을 막아줌(원 상태 그대로 - 하나의 명령으로)
$ echo "~"

$ echo $(cal)
$ echo "$(cal)"