Decorator Pattern

7259 단어 DesignPatterns

자기 소개

  • 이름: 정창지 (몽골)
  • 소속: 코드아트주식회사
  • 소속:] 5j 가고시마
  • 취미: 오토바이
  • 의사 일정


    오늘은 디자인 모드.
    디자인 모드를 사용하면...
    이렇게 할 수 있어요.
    기억해 주시면 좋을 것 같아요.
    디자인 패턴의 형상보다
    좋은 점 이해해주세요.

    샘플 코드


    GiitHub 창고의 콘솔 응용 프로그램 검색
    시험해 보다
    $ ./gradlew run -q
    GitHub Repository の検索キーワードを入力してください:
    aratana
    mwtestlab/aratana => https://github.com/mwtestlab/aratana
    yamakei7323/aratanaIntern => https://github.com/yamakei7323/aratanaIntern
    tao1027/aratana-test => https://github.com/tao1027/aratana-test
    High-Hill/aratana-intern => https://github.com/High-Hill/aratana-intern
    takashi1029/aratana_intern => https://github.com/takashi1029/aratana_intern
    papuaaaaaaa/yakitori => https://github.com/papuaaaaaaa/yakitori
    AratanaLab/aratanalab.github.com => https://github.com/AratanaLab/aratanalab.github.com
    abehazuki/knowlege => https://github.com/abehazuki/knowlege
    GitHub Repository の検索キーワードを入力してください:
    
    이런 느낌.
    처리하는 절차가 이런 느낌이에요. GiitHub API 호출이 이런 느낌이에요. public class GitHubApi { private final WebTarget target; public GitHubApi() { Client client = ClientBuilder.newClient(); target = client.target("https://api.github.com/search/repositories"); } public RepositoriesResult searchRepositories(String keyword) { return target .queryParam("q", keyword) .request(MediaType.APPLICATION_JSON_TYPE) .get(RepositoriesResult.class); } } GiitHub API를 호출해서 결과를 회신했을 뿐입니다! 입력을 받는 느낌. public class Ui { private final GitHubApi api; public Ui() { api = new GitHubApi(); } public void searchRepositories() { while (true) { String input = getInput(); if (Objects.equals(input, "")) break; RepositoriesResult result = api.searchRepositories(input); display(result); } } private String getInput() { InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); System.out."GiitHub Repository"에 대한 검색 키워드를 입력하십시오. try { return br.readLine(); } catch (IOException e) { e.printStackTrace(); return null; } } private void display(RepositoriesResult result) { for (Repository repo : result.getItems()) { System.out.println(repo.getFull_name() + " => " + repo.getHtml_url()); } } } 내장 캐시 메시지 좀 늦어서 캐시하고 싶어요! 여러분 어떡하죠? 여기, 만지고 싶지 않아요? public class GitHubApi { private final WebTarget target; public GitHubApi() { Client client = ClientBuilder.newClient(); target = client.target("https://api.github.com/search/repositories"); } public RepositoriesResult searchRepositories(String keyword) { //여기 만지고 싶지 않아요? return target .queryParam("q", keyword) .request(MediaType.APPLICATION_JSON_TYPE) .get(RepositoriesResult.class); } } 저는 개인적으로 추천하지 않습니다! 이런 수정을 여러 번 반복하면 혼돈이 돼요. 조금씩 설명하다 GiitHubApi 클래스가 수정되면... Ui 클래스를 수정하면... 복사하면... 뭐가 좋을까... 장래가 어떻게 될지 생각하고 가장 적합한 것을 선택해라... 수단을 가리지 않다 되도록 다시 쓰지 마세요! 이런 거 아니야! 이런 거 아니야! 그렇습니다! 이런 느낌. 다만, Ui반에 영향을 미칠 수 있다
    한 줄만 수정하면 돼요. public class Ui { private final GitHubApi api; public Ui() { // api = new GitHubApi(); api = new CacheGitHubApi(new GitHubApi()); } // ...snip } abstract 클래스 분리 인터페이스 및 설치 사용 역시 인터페이스 분리 인터페이스 사용 및 실현 abstract class와interface 어떤 것이 좋아요? 최대한 인터페이스로! 하지만 인터페이스라면 문제가 생길 때가 있다 자바는interface의 기본 구현으로 해결 .NET Framework는 확장을 통해 해결 이 근처에 손을 대주세요. 장점 쓰는 쪽은 팍팍 할 수 있어요. 곧 원상회복 단일 테스트는 하기 쉽다 미룰 수 있다 쓰는 쪽은 팍팍 할 수 있어요. // 캐시 없음 api = new RawGitHubApi(); // 캐시 포함 api = new CacheGitHubApi(new RawGitHubApi()); // API 호출 시 로그 출력 api = new CacheGitHubApi(new LogGitHubApi(new RawGitHubApi())); 곧 원상회복 CacheGiitHubApi류가 고장나도 그렇게 무섭지 않아요! // api = new RawGitHubApi(); api = new CacheGitHubApi(new RawGitHubApi()); 단일 테스트는 하기 쉽다 캐시가 있는지 없는지 손으로 테스트하는 게 굉장히 어려워요. MockGitHubApi mock = new MockGitHubApi(); // 테스트용 모듈 GitHubApi target = new CacheGitHubApi(mock); // 캐시 없음, 호출 API target.searchRepositories("abc"); assertEquals(mock.callCount(), 1); // 캐시 성공, API 호출 안 함 target.searchRepositories("abc"); assertEquals(mock.callCount(), 1); // 다른 키워드로 검색할 때 캐시하지 않음 target.searchRepositories("def"); assertEquals(mock.callCount(), 2); 미룰 수 있다 API를 캐시하는 방법은 상당히 어려운 문제입니다. 이번에는 현금이 없어서 현금으로 바꿨어요. 즉, 프로그램을 쓰기 전에 결정할 필요가 없다는 것이다 애플리케이션 가치에 더욱 근접한 곳에 집중한 후 조정 decorator 모드의 사용 방법 캐시 실무, 일, 총무 저널 예: 감찰을 위해 한동안 우편물만 보내다 디자인할 때 뜨개질하지 않은 것도 처리하기 쉽다 즉석에서 대처하다 예: 계산 모드가 잘못되었습니다. 근본적인 잘못을 찾아내기 전에 잠시 대처하기 위해서. 다른 것도 많은 것 같은데! AOP(경품) 로그 캐시 거래에서 유사한 코드가 많이 발생합니다 // 이런 형식의 코드가 대량으로 생성 log.start("foo.method1()"); try { foo.method1(); } catch (Exception ex) { log.exception(ex); throw ex; } log.end("foo.method1()"); 이건 데코레이터 모드로도 해결이 안 돼요. class LogFoo extends Foo {} class LogBar extends Bar {} class LogBazz extends Bazz {} AOP을 사용하면 decorator를 자동으로 생성할 수 있습니다 크게 두 종류로 나뉜다 런타임 시 동적으로 생성되는 유형 컴파일 전 생성 클래스의 유형 추가 과제 Huzuon의 도전과제를 받아들일 필요가 없어요. 이 아코디언의 앱은 세 회사(A, B, C)에서 판매될 것이다.하지만 요구는 좀 다르다. A:이렇게 됐으면 좋겠어요! B:현금카드는 예전에 고생한 적이 있어요.네트워크를 강화해야 하기 때문에 캐시를 하지 마세요. C:캐시 알고리즘은 특허가 있기 때문에 이쪽에서 코드를 씁니다.아, 코드를 공개할 수 없네! 총결산 decorator 도형을 이용하는 쪽은 툭툭 할 수 있어요. 쓸 만하면 몇 가지 문제의 해결을 미룰 수 있다 디자인 모드를 잘 사용할 수 있을 때 즐겁습니다!

    좋은 웹페이지 즐겨찾기