하나의 모듈은 하나의, 오직 하나의 액터에 대해서만 책임져야 한다.
하나의 모듈에 대해 여러 액터가 의존하고 있다면 각각의 액터가 의존하고 있는 메서드를 별도의 클래스로 분리 시켜야 한다. 이로 인해 인스턴스 관리의 어려움이 발생할 수 있는데 퍼사드(Facade) 패턴을 통해 해결할 수 있다.
퍼사드(Facade) 패턴 - 서브시스템을 간편하게 사용하기 위해 인터페이스를 사용하는 패턴. 실제 구현은 서브시스템이 하기 때문에 퍼사드 클래스에서는 구현을 신경쓸 필요가 없다.
소프트웨어 개체(artifact)는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
아키텍처 수준에서 OCP는 수준에 따라 보호의 계층구조를 나누고 고수준의 컴포넌트를 저수준의 컴포넌트에서 발생한 변경으로부터 보호한다.
HOW? 저수준의 컴포넌트가 고수준의 컴포넌트를 의존하는 단방향 의존을 통해서. 고수준의 컴포넌트는 저수준의 컴포넌트를 의존하지 말아야 한다.
S 타입의 객체 o1 각각에 대응하는 T 타입 객체 o2가 있고, T타입을 이용해서 정의한 모든 프로그램 P에서 o2의 자리에 o1을 치환하더라도 P의 행위가 변하지 않는다면, S는 T의 하위 타입이다.
인터페이스와 구현체를 기준으로 했을 때 둘 사이에는 LSP가 성립된다.
LSP를 위반하는 케이스가 발생할 경우 해당 엣지 케이스를 처리하는 복잡한 매커니즘을 추가해야 하므로 주의해야 한다.
필요 이상으로 많은 걸 포함하고 있는 모듈에 의존하는 것은 해로운 일이다.
언어의 종류(정적, 동적)에 따라 ISP에 영향을 받는 정도가 다르다. (소스코드 변경에 따른 재컴파일과 재배포 유무)
인터페이스를 분리하는 것으로 불필요한 기능에 의존하는 것을 방지할 수 있다.
소스 코드 의존성이 추상에 의존하며 구체(구현)에는 의존하지 않는 시스템
운영체제나 플랫폼 같이 안정성이 보장된 환경에 대한 의존성은 무시하되 변동성이 큰 구체, 즉 개발중인 모듈들에 대한 의존성을 피해야 한다.
추상에 의존하는 것으로 제어 흐름은 의존성과 정반대 방향으로 역전된다. (Dependency Inversion)
의존성은 더 추상적인 엔티티가 있는 쪽으로만 향한다. (Dependency Rule)