문제

내 시스템에 한 번만 존재하고 기본적으로 내 애플리케이션의 다양한 작업에 대한 다양한 권한을 관리하는 기능을 수행하는 PermissionManager라는 클래스가 있다고 가정해 보겠습니다.이제 내 애플리케이션에는 메서드 중 하나에서 특정 권한을 확인할 수 있는 클래스가 있습니다.이 클래스의 생성자는 현재 공개되어 있습니다.API 사용자가 사용합니다.

몇 주 전까지만 해도 저는 수업에서 어딘가에 다음 의사 코드를 호출하도록 했습니다.

     PermissionManager.getInstance().isReadPermissionEnabled(this)

그러나 여기 있는 모든 사람들이 싱글톤 + 이런 종류의 결합을 싫어한다는 것을 알았기 때문에, 싱글톤에 대해 내가 읽은 주장이 의미가 있는 것 같기 때문에(테스트 불가능, 높은 결합 등) 더 나은 솔루션이 무엇인지 궁금했습니다.

그렇다면 실제로 API 사용자에게 클래스 생성자에 PermissionManager 인스턴스를 전달하도록 요구해야 합니까?내 애플리케이션에 대해 단일 PermissionManager 인스턴스만 존재하기를 원하는데도 어떻게 되나요?

아니면 내가 이 모든 일을 잘못하고 있는 걸까요? 비공개 생성자와 나를 위해 PermissionManager 인스턴스를 전달하는 팩토리가 어딘가에 있어야 합니까?


추가 정보 내가 "종속성 주입"이라고 말할 때는 DI에 대해 말하는 것입니다. 무늬...Guice나 Spring과 같은 DI 프레임워크를 사용하지 않습니다.(...아직)

도움이 되었습니까?

해결책

종속성 주입 프레임워크를 사용하는 경우 이를 처리하는 일반적인 방법은 생성자의 PermissionsManager 개체를 전달하거나 프레임워크가 설정하는 PermissionsManager 유형의 속성을 갖는 것입니다.

이것이 가능하지 않다면 사용자가 팩토리를 통해 이 클래스의 인스턴스를 얻도록 하는 것이 좋은 선택입니다.이 경우 팩토리는 클래스를 생성할 때 PermissionManager를 생성자에 전달합니다.애플리케이션 시작 시 먼저 단일 PermissionManager를 만든 다음 팩토리를 만들고 PermissionManager를 전달합니다.

클래스의 클라이언트가 올바른 PermissionManager 인스턴스를 찾아서 전달하는 위치를 아는 것(또는 클래스가 PermissionManager를 사용한다는 사실에 관심을 두는 것)이 일반적으로 다루기 어렵다는 것이 맞습니다.

내가 본 한 가지 절충안은 클래스에 PermissionManager 유형의 속성을 제공하는 것입니다.속성이 설정된 경우(예: 단위 테스트에서) 해당 인스턴스를 사용하고, 그렇지 않으면 싱글톤을 사용합니다.다음과 같은 것 :

PermissionManager mManager = null;
public PermissionManager Permissions
{
  if (mManager == null)
  {
    return mManager;
  }
  return PermissionManager.getInstance();
}

물론 엄밀히 말하면 PermissionManager는 일종의 IPermissionManager 인터페이스를 구현해야 합니다. 그건 테스트 중에 더미 구현을 더 쉽게 대체할 수 있도록 다른 클래스에서 참조해야 하는 내용입니다.

다른 팁

실제로 허가 관리자를 주입하여 시작할 수 있습니다. 이렇게하면 수업을 더욱 테스트 할 수 있습니다.

해당 클래스 사용자에게 문제가 발생하면 공장 방법이나 추상 공장을 사용할 수 있습니다. 또는 테스트는 허가 관리자를 조롱하는 데 사용할 수있는 다른 생성자를 사용하는 동안 해당 파라미터가없는 생성자를 추가 할 수 있습니다.

수업을 분리하면 수업이 더욱 유연 해지지만 사용하기가 더 어려워 질 수 있습니다. 그것은 당신이 필요로하는 상황에 달려 있습니다. 허가 관리자가 하나만 있고이를 사용하는 클래스를 테스트하는 데 문제가없는 경우 DI를 사용할 이유가 없습니다. 사람들이 자신의 허가 관리자 구현을 추가 할 수 있기를 원한다면 DI가 갈 길입니다.

종속성 주입 방식을 구독하고 있다면 어떤 클래스든 필요합니다. PermissionManager 객체 인스턴스로 주입해야 합니다.인스턴스화를 제어하는 ​​메커니즘(싱글톤 특성을 적용하기 위해)은 더 높은 수준에서 작동합니다.Guice와 같은 종속성 주입 프레임워크를 사용하면 시행 작업을 수행할 수 있습니다.개체 연결을 수동으로 수행하는 경우 종속성 주입은 비즈니스 논리에서 벗어나 인스턴스화(새 운영자 작업)를 수행하는 그룹화 코드를 선호합니다.

그러나 어느 쪽이든, 고전적인 "capital-S" 싱글톤은 일반적으로 종속성 주입의 맥락에서 안티 패턴으로 간주됩니다.

다음 게시물은 과거에 저에게 통찰력이 있었습니다.

실제로 API 사용자가 클래스 생성자의 허가 관리자 인스턴스를 전달해야합니까? 내 응용 프로그램에 단일 허가 관리자 인스턴스 만 존재하기를 원하십니까?

예, 이것이 당신이해야 할 전부입니다. 종속성이 싱글 톤 / 당 요청 / 스레드 당 또는 공장 방법인지 여부는 컨테이너 및 구성의 책임입니다. .NET 세계에서 우리는 커플 링을 더욱 줄이기 위해 iPerMissionsManager 인터페이스에 대한 의존성을 이상적으로 사용합니다. 이것이 Java의 모범 사례라고 가정합니다.

싱글 톤 패턴은 그 자체로 나쁘지 않습니다. 추악하게 만드는 것은 일반적으로 사용되는 방식입니다. 특정 클래스의 단일 인스턴스 만 원한다는 요구 사항이기 때문에 큰 실수라고 생각합니다.

이 경우 어떤 이유로 든 Istanciable 유형이어야하지 않는 한 AmermissionManager를 정적 클래스로 만들게됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top