개방 폐쇄 원칙

이제 두 번째 SOLID 원칙인 Open-Closed로 또 다른 여정을 시작할 때입니다.

개방 폐쇄 원칙은 다음과 같이 말합니다.

“Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”



그게 무슨 뜻이야? 어떻게 소프트웨어 개체를 동시에 열고 닫을 수 있습니까!

문제를 설명하기 위해 실제 시나리오를 사용하여 설명을 시작한 다음 솔루션 및 기술 세부 정보로 이동하겠습니다.

class PhotoViewer{
    void openPhoto(){
        System.out.println("Open JPEG photo!");  
    }
}


이제 사진 뷰어 클래스를 작성했으며 JPEG 사진만 열어야 한다고 확신합니다. 나중에 사용자가 계속해서 PNG 사진을 보려고 한다는 것을 알게 되었습니다. 그리고 앱이 지원하지 않기 때문에 오류가 발생합니다. 그래서 PNG를 지원하도록 소스 코드를 편집하기로 결정했습니다.

class PhotoViewer{  
    void openPhoto(String type){
        if(type == "JPEG"){      
            System.out.println("Open JPEG photo!");
        }    
        else if(type == "PNG"){
            System.out.println("Open PNG photo!");    
        }
        else{
            System.out.println("Photo type is not supported!");
        }
    }
}


이제 변경한 후 코드의 문제는 무엇입니까?

다른 유형을 추가하기로 결정했다면? 지금과 그때가 100% 어떤 일이 일어날까요?

그 순간 다른 if 문을 추가합니다. 새로운 유형을 연이어 추가하면 열린 사진 기능이 기능으로 너무 커집니다. 그리고 모든 유형이 같은 위치에 있기 때문에 한 유형에서 일부 코드 행을 제거하면 다른 유형이 충돌할 수 있습니다.

따라서 코드는 확장을 위해 열려 있습니다. 즉, 다른 기능으로 확장할 수 있습니다. 그러나 유형을 추가할 때마다 열려 있는 사진 기능 코드 행을 수정하기 때문에 수정을 위해 닫히지 않았습니다. 여러 가지 이유로 동일한 코드 블록에서 많은 변경 사항은 잘못된 디자인을 나타냅니다.

좋습니다. 사진 뷰어 클래스에서 JPEG와 PNG를 서로 다른 기능으로 분리하는 것에 대해 생각했을 수도 있습니다. 나는 당신과 함께, 그것을 시도하자!

class PhotoViewer{  
    void openJpegPhoto(){    
        System.out.println("Open JPEG photo!");
    }
    void openPngPhoto(){
        System.out.println("Open PNG photo!");
    }
}


이제 코드를 확장할 수 있습니다. 새로운 기능을 추가하여 새로운 유형을 쉽게 추가할 수 있습니다. 그러나 동일한 문제가 여전히 존재합니다. 코드의 클래스 라인이 변경 사항의 영향을 받을 것이기 때문에 솔루션은 수정을 위해 100% 닫혀 있지 않습니다. 또한 사진 뷰어 클래스에 다른 유형을 추가하면 더 많은 책임과 함께 더 크게 만들 것입니다. 이는 단일 책임 원칙에 위배됩니다.

당신이 피곤하다는 것을 알고 있지만 나를 믿으십시오. 그만한 가치가 있습니다.

솔루션은 모든 새로운 유형이 구현할 수 있는 일반 사진 유형을 나타내기 위해 일반 인터페이스를 사용하여 객체 지향 프로그래밍 기능을 사용하는 것입니다.

interface Photo{
    void open();
}

class PhotoJpeg implements Photo{  
    void open(){    
        System.out.println("Open JPEG photo!");  
    }
}

class PhotoPng implements Photo{
    void open(){    
        System.out.println("Open PNG photo!");  
    }
}

class PhotoViewer(){  
    void openPhoto(Photo photo){    
        photo.open();  
    }
}


새 유형을 추가해도 소스 코드에서 한 줄의 코드도 변경되지 않음을 알 수 있습니다. 새로운 유형의 사진 인터페이스를 구현하고 사진을 사진 뷰어로 보내 열면 됩니다.

class PhotoGif implements Photo{  
    void open(){    
        System.out.println("Open GIF photo!");  
    }
}


솔루션은 확장을 위해 100% 개방되어 있고 수정을 위해 폐쇄되어 있습니다. 단일 책임 원칙도 적용됩니다.

이제 Open-Closed는 코드가 새로운 기능에 의해 확장될 수 있도록 열려 있고 소스 코드를 변경하지만 추가한다는 측면에서 닫혀 있음을 의미합니다.

세 번째 SOLID 원칙, Liskov Substitution과 함께 새로운 여정을 기다리십시오!

사진 뷰어는 말 그대로 모든 곳에서 사용됩니다. 페이스북이나 트위터와 같은 소셜 미디어 플랫폼에서 찾을 수 있습니다. 또한 스마트폰에서 갤러리 애플리케이션으로 찾을 수 있습니다. 많은 앱에서 핵심 기능으로 간주됩니다.

자신의 사진 뷰어를 개발하기로 결정했다면 사용자는 모든 유형의 사진을 열 수 있기를 기대합니다. JPEG 사진일 수 있습니다. PNG일 수도 있습니다. 사진 뷰어에서 특정 유형을 지원하지 않는 경우가 있습니다. 따라서 해당 유형을 지원하려면 사진 뷰어의 소스 코드를 변경해야 합니다.

사진 뷰어에 추가된 새 유형이 이미 존재하는 유형에 영향을 미치지 않도록 하는 방법은 무엇입니까? GIF 유형을 지원하도록 응용 프로그램을 편집할 수 있지만 PNG 사진을 열면 응용 프로그램이 충돌합니다. 그런 일이 발생하지 않도록 하는 방법은 무엇입니까? 그리고 미래에 서로 영향을 미치지 않고 다른 유형을 추가하고 제거할 수 있는 충분한 유연성을 보장하는 방법.

해결책은 확실히 짐작할 수 있듯이 개방-폐쇄 원칙입니다.

약간의 변경으로 단일 책임 문서에서 PhotoViewer 클래스를 호출합니다.

좋은 웹페이지 즐겨찾기