2016-10-16 3 views
1

저는 SRP (Single Responsibility Principle)를 위반하지 않도록 다시 고려해야 할 코드가 있습니다.단일 책임 원칙 리팩터링

나는 아래의 클래스가 여러 이유로 변경 될 수 있음을 이해 :

  • 업로드 방법을 변경할 수
  • 메타 데이터 스키마를 변경할 수 분석을위한

    • 비즈니스 규칙 그러나

    을 변경할 수 있습니다, 나는 내가 어떻게 다른 수업에 다시 배울 수 있는지 알아내는 데 어려움을 겪고있다.

    는 Engine.java

    package com.example; 
    
    import java.util.List; 
    
    public interface Engine { 
        public List<Recording> analyze(List<String> files); 
        public List<Recording> getMetadata(List<Recording> recordings); 
        public List<Recording> upload(List<Recording> recordings); 
    } 
    

    CallEngine.java

    package com.example; 
    
    import java.util.ArrayList; 
    import java.util.List; 
    import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory; 
    
    public class CallEngine implements Engine { 
    
        final static Logger log = LoggerFactory.getLogger(Main.class); 
    
        public List<Recording> analyze(List<String> files) { 
        log.info("Analyzing recording files per business rules..."); 
    
        List<Recording> recordings = new ArrayList<Recording>(); 
        return recordings; 
        } 
    
        public List<Recording> getMetadata(List<Recording> r) { 
        log.info("Retrieving metadata for calls..."); 
        List<Recording> recordings = new ArrayList<Recording>(); 
        return recordings; 
        } 
    
        public List<Recording> upload(List<Recording> r) { 
        log.info("Uploading calls..."); 
        List<Recording> recordings = new ArrayList<Recording>(); 
        return recordings; 
        } 
    } 
    
  • 답변

    1

    SRP에 주로 인터페이스 뒤에 코드 추출과 관련없는 기능을 책임 위임을 통해 이루어진다는 어느에 구현 뒤에 우연히 실행시의 인터페이스

    이 경우 자신의 인터페이스 뒤에 책임을 추상화해야합니다. 예를 들어

    ...

    public interface Analyzer { 
        public List<Recording> analyze(List<String> files); 
    } 
    public interface Retriever { 
        public List<Recording> getMetadata(List<Recording> recordings); 
    } 
    public interface Uploader { 
        public List<Recording> upload(List<Recording> r); 
    } 
    

    그리고는 Engine 구현의 분사-수 의존성로 있습니다.

    public class CallEngine implements Engine { 
        private Analyzer analyzer; 
        private Retriever retriever; 
        private Uploader uploader; 
    
        public CallEngine(Analyzer analyzer, Retriever retriever, Uploader uploader) { 
         this.analyzer = analyzer; 
         this.retriever = retriever; 
         this.uploader = uploader;   
        } 
    
        public List<Recording> analyze(List<String> files) { 
         return analyzer.analyze(files); 
        } 
    
        public List<Recording> getMetadata(List<Recording> r) { 
         return retriever.getMetadata(r); 
        } 
    
        public List<Recording> upload(List<Recording> r) { 
         return uploader.upload(r); 
        } 
    } 
    

    런타임 구현은 종속 클래스 구현의 전반적인 책임에 영향을 미치지 않고 변경할 수 있으므로 변경에 훨씬 적응할 수 있습니다.

    1
    public interface Analyzer { 
        public void analyze(); 
    } 
    public interface Retriever { 
        public void retrieveMetadata(); 
    } 
    public interface Uploader { 
        public void upload(); 
    } 
    
    public class EngineAnalyzer implements Analyzer { 
    
        final static Logger log = LoggerFactory.getLogger(Main.class); 
    
        public List<Recording> recordings; 
    
        EngineAnaylzer(List<String> Files) { 
    
        } 
    
        public void analyze() { 
        log.info("Analyzing recording files per business rules..."); 
        } 
    
    } 
    
    관련 문제