문제

'Application' 클래스가 있다고 가정해 보겠습니다.초기화하려면 생성자에서 특정 설정이 필요합니다.또한 설정 수가 너무 많아서 고유한 클래스에 배치하는 것이 설득력이 있다고 가정해 보겠습니다.

이 시나리오의 다음 두 가지 구현을 비교하십시오.

구현 1:

class Application 
{
   Application(ApplicationSettings settings) 
   {
       //Do initialisation here
   }
}

class ApplicationSettings 
{
   //Settings related methods and properties here
}

구현 2:

class Application 
{
   Application(Application.Settings settings) 
   {
       //Do initialisation here
   }

   class Settings 
   {
      //Settings related methods and properties here
   }
}

나에게는 두 번째 접근 방식이 매우 바람직합니다.두 클래스 간의 관계를 강력하게 강조하기 때문에 더 읽기 쉽습니다.어디서나 Application 클래스를 인스턴스화하는 코드를 작성할 때 두 번째 접근 방식이 더 예뻐 보일 것입니다.

이제 설정 클래스 자체에 비슷한 "관련" 클래스가 있고 해당 클래스도 그렇게 했다고 상상해 보십시오.이러한 수준을 세 개만 진행하면 '중첩되지 않은' 경우 클래스 이름 지정이 불가능해집니다.그러나 중첩하면 여전히 우아한 상태를 유지합니다.

위의 내용에도 불구하고 나는 StackOverflow에서 중첩 클래스가 외부 세계에 표시되지 않는 경우에만 정당화된다는 사람들의 말을 읽은 적이 있습니다.즉, 포함 클래스의 내부 구현에만 사용되는 경우입니다.일반적으로 인용되는 반대 의견은 포함된 클래스의 소스 파일 크기가 너무 커지는 것입니다. 그러나 부분 클래스는 이 문제에 대한 완벽한 솔루션입니다.

내 질문은 중첩 클래스의 "공개적으로 노출된" 사용을 왜 경계해야 하는가입니다.그러한 사용에 반대하는 다른 주장이 있습니까?

도움이 되었습니까?

해결책

내 생각엔 괜찮을 것 같아.이것은 기본적으로 빌더 패턴이며 중첩 클래스를 사용하면 꽤 잘 작동합니다.또한 빌더가 외부 클래스의 전용 멤버에 액세스할 수 있게 해 주는데 이는 매우 유용할 수 있습니다.예를 들어, 빌더의 인스턴스를 취하는 외부 클래스의 전용 생성자를 호출하는 빌더의 Build 메서드를 가질 수 있습니다.

public class Outer
{
    private Outer(Builder builder)
    {
        // Copy stuff
    }

    public class Builder
    {
        public Outer Build()
        {
            return new Outer(this);
        }
    }
}

이는 오직 외부 클래스의 인스턴스를 빌드하는 방법은 빌더를 이용하는 것입니다.

저는 프로토콜 버퍼의 C# 포트에서 이와 매우 유사한 패턴을 사용합니다.

다른 팁

네임스페이스를 사용하여 다음과 같은 항목을 연결할 수 있습니다.관련된.

예를 들어:

namespace Diner
{
    public class Sandwich
    {
        public Sandwich(Filling filling) { }
    }

    public class Filling { }
}

클래스를 네임스페이스인 것처럼 사용하는 것보다 이 방법의 장점은 선택적으로 다음을 사용할 수 있다는 것입니다. using 호출 측에서 내용을 단축합니다.

using Diner;

...

var sandwich = new Sandwich(new Filling());

당신이 사용하는 경우 Sandwich 클래스는 마치 네임스페이스인 것처럼 보입니다. Filling, 전체 이름을 사용해야 합니다. Sandwich.Filling 참조하다 Filling.

그리고 그걸 알면서 밤에 어떻게 잠을 잘 수 있나요?

당신은 무엇을 확인하고 싶을 수도 있습니다 마이크로소프트가 말해야 할 것 주제에.기본적으로 제가 말하고 싶은 것은 스타일의 문제입니다.

공개 중첩 클래스를 올바르게 사용하기 위한 또 다른 실제적인 예는 IEnumerable 속성이 있는 뷰 모델을 사용할 때 MVC 패턴입니다.예를 들어:

public class OrderViewModel
{
public int OrderId{ get; set; }
public IEnumerable<Product> Products{ get; set; }

public class Product {
public string ProductName{ get; set; }
public decimal ProductPrice{ get; set; }
}

}

원하지 않기 때문에 사용합니다 Product 클래스는 해당 클래스를 포함하는 특정 뷰 모델에 대해서만 사용자 정의되므로 외부에서 재사용할 수 있습니다.하지만 Products 속성이 공개이므로 비공개로 설정할 수 없습니다.

저는 중첩 클래스 및/또는 컨테이너 클래스에 대한 액세스를 미세 조정하기 위해 주로 중첩 클래스를 사용합니다.

한 가지 기억해야 할 점은 중첩 클래스 정의는 기본적으로 클래스 멤버이며 모든 컨테이너의 전용 변수에 액세스할 수 있다는 것입니다.

이를 사용하여 특정 클래스의 사용을 제어할 수도 있습니다.

예:

public abstract class Outer
{
  protected class Inner
  {
  }
}

이제 이 경우 사용자(클래스의)는 Outer를 구현하는 경우에만 Inner 클래스에 액세스할 수 있습니다.

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