2012-10-04 4 views
3

사용자 지정 파일에 액세스하기 위해 두 개의 별도 클래스를 만들고 있습니다. 수업 내용을 MyReaderMyWriter으로합시다.여러 클래스에 공통 설정을 저장하기위한 최적의 패턴

동일한 패턴을 따르고 있습니다. 예를 들어, StreamReaderStreamWriter과 같은 .NET 클래스는 읽기 및 쓰기 용으로 별도의 클래스가 있습니다. 확립 된 패턴을 따르는 것 외에도, 이것은 나에게 또 다른 문제점들을 해결했다.

그러나 리더 및 라이터 클래스에 대해 몇 가지 공통 설정이 필요합니다. 예를 들어, 사용자가 변경할 수 있어야하는 분리 문자가 있습니다. 또한 파싱에 사용되는 공통 정보가 포함 된 고정 데이터가 있습니다.

누군가가 좋은 패턴, 특히 일반적인 .NET 프레임 워크 방식을 따르는 패턴을 제안하여 여러 가지 클래스에 대한 공통 설정을 만들 수 있습니까? 내 클래스는 이미 .NET 클래스에서 상속받습니다. 여러 상속이 한 방법일지도 모르지만 C#에서는 지원되지 않는 것처럼 보입니다.

답변

1

는 이것을 Singleton 좋은 적합 할 수 있습니다 그 드문 경우 중 하나가 될 것으로 보인다.

+0

감사합니다. 나는 지금까지 이걸 신중하게 검토 할 기회를 얻지 못했다. 솔직히이 코드의 대부분이 왜 필요한지 이해할 수 없습니다. 'MyReader'와'MyWriter'의 모든 인스턴스가'MySettings'의 동일한 인스턴스를 참조하여 나타나기 때문에'MySettings'을 정적으로 만들고 그것을 직접 참조하지 않는 것이 어떻습니까? 왜 모든 인터페이스, 상속 및 개인 클래스가 필요합니까? –

+0

단위 테스트 가능성, 느슨한 결합, 필요하면 객체 상속 기능이 있습니다. 그 중 일부입니다. 필자는 tranceporter를 사용하여 생성자를 통해 주입 할 가능성이 높지만 .NET FCL이하는 것과 다른 것이므로 몇 가지 모범 사례를 통해이를 에뮬레이션하려고했습니다. –

1

이 인터페이스를 사용해보십시오 (I 비주얼 스튜디오 2012을 사용하고 있습니다). interfaceabstract class과 같이 작동하지만이를 구현하는 클래스가 "fleshed out"할 메서드 또는 속성 정의 만 포함 할 수 있습니다. 그런 다음 클래스는 필요한만큼의 인터페이스를 구현할 수 있습니다. IEnumerable은 목록, 사전 및 배열 모두가 공통적 인 메서드 집합을 공유하여 foreach에 사용되도록 허용하거나 IDisposable이 클래스를 using에 선언하는 방법을 허용하는 방법을 살펴보십시오.

여러 응용 프로그램의 사용자 구성에서 표시 스타일 설정을 가져 오는 일련의 잉크 텍스트 상자 컨트롤을 만들었으므로 IInkInputSettings 인터페이스에서 해당 설정을 가져 와서 모든 응용 프로그램에서 해당 인터페이스를 구현했습니다 'UserConfig 클래스.

또는, 싱글의 방법으로 글로벌 구성을 달성 할 수 :

public class GlobalConfig{ 
    /* your configuration properties here */ 
    private static GlobalConfig instance = null; 
    public static GlobalConfig Instance{ 
     get{ 
      if(instance == null) instance=new GlobalConfig(); 
      return instance; 
     } 
    } 
    private GlobalConfig(){ /* set default property values */ } 
} 

이것은 정적 멤버와 정적 클래스보다 낫다을, 그것은 단지 당신이 그것을 처음 사용할 때 인스턴스화되기 때문이다. 이 도움이

public abstract class MyBase 
{ 
    // This is the .NET class you're inheriting from, just putting it as a placeholder. 
} 

public class MyReader : MyBase 
{ 
    private static readonly IMySettings settings = MySettings.Instance; 
} 

public class MyWriter : MyBase 
{ 
    private static readonly IMySettings settings = MySettings.Instance; 
} 

internal interface IMySettings 
{ 
    // Define your setting's properties, such as delimiter character. 
} 

internal sealed class MySettings : IMySettings 
{ 
    private MySettings() 
    { 
    } 

    public static IMySettings Instance 
    { 
     get 
     { 
      return Nested.Instance; 
     } 
    } 

    // Implement your setting's properties, such as delimiter character. 

    private static class Nested 
    { 
     private static readonly IMySettings instance = new MySettings(); 

     // Explicit static constructor to tell C# compiler not to mark type as beforefieldinit 
     static Nested() 
     { 
     } 

     public static IMySettings Instance 
     { 
      get 
      { 
       return instance; 
      } 
     } 
    } 
} 

희망 :

+0

감사합니다. 그러나 이것이 어떻게 도움이 될지 모르겠습니다. 그것은 인터페이스를 정의 할 것이지만, 여전히 두 개의 다른 장소에서 그 인터페이스를 구현해야 할 것입니다. 필자가 이상적으로 생각하는 시나리오는 사용자가 구분 문자를 한 곳에서 설정할 수 있으며 읽기 및 쓰기 클래스에 모두 영향을 미친다는 것입니다. –

+0

두 클래스의 모든 인스턴스에 영향을 미치시겠습니까? 싱글 톤으로 그렇게 할 수 있습니다. – Patrick

+0

잘 모르겠습니다. 제가 설명했던 두 가지 수업으로 어떻게 구현 될 수 있는지 자세히 설명해 주시겠습니까? –

1

생성자 기반 종속성 삽입을 사용하여 설정 클래스를 클래스에 삽입 할 수 있습니다. IoC 컨테이너에서 설정 클래스, 싱글 톤 또는 비공유를 생성하고 기본 클래스 나 인터페이스를 기반으로 주입하는 것은 간단합니다.

3
public interface IStreamFilter 
{ 
    string Delimiter {get; private set;} 
    List<string> FilterCriteria {get; private set;} 
} 

public class StreamFilter : IStreamFilter 
{ 
    public string Delimiter {get;} 
    public List<string> FilterCriteria {get;} 

    public void StreamFilter (string delimiter, List<string> filterCriteria) 
    { 
     this.Delimiter = delimiter; 
     this.FilterCriteria = filterCriteria; 
    } 
} 

리더 및 라이터 클래스의 생성자에서 IStreamFilter의 인스턴스를 전달할 수 있습니다. 당신이 MyReader 클래스의 인스턴스를 원하는 어느 곳 코드에서

public class MyReader 
{ 
     private IStreamFilter _streamFilter; 

     public MyReader(IStreamFilter streamFilter) 
     { 
      this._streamFilter = streamFilter; 
     } 

     public string ReadString() 
     { 
      var readString = reader.GetString(x => x.Contains(this._streamFilter.Delimiter); 
      // apply the filter for reading string 
     } 
} 

, 당신은에, 사용자 환경에 따라 (의 사용자 프로필에서 가정 해 봅시다) IStreamFilter의 새로운 인스턴스를 생성하고, 구분 기호 및 기타 필터 기준을 설정할 수 있습니다 건설자. 그런 다음 StreamFilter의 해당 인스턴스를 MyReader 인스턴스로 전달합니다. 그렇게하면 싱글 톤에 의존하지 않고 즉석에서 필터 설정을 사용자 정의 할 수 있습니다.

관련 문제