C #에서 '전역'변수를 캡슐화하는 방법은 무엇입니까? / 모범 사례


9

C #에서 여러 방법에 사용해야하는 변수를 캡슐화하는 가장 좋은 방법은 무엇입니까? 단순히 두 가지 방법으로 클래스 상단에 선언해도 괜찮습니까?

또한 구성 파일에서 앱 설정을 사용하는 경우 getter를 사용해야합니까? 이렇게 ...

private string mySetting{ get { return WebConfigurationManager.AppSettings["mySetting"]; } }

모범 사례는 무엇입니까?


간접적 (필요하지 않은) 추가 계층을 추가하는 것 외에 게터의 목적은 무엇입니까?
Robert Harvey

4
Getter는 WebConfigurationManager.AppSettings나중에 변경하기가 훨씬 쉬워 여러 번의 호출보다 훨씬 낫습니다.
Daniel Little

@Lavinski : 물론 데이터 저장소를 나중에 다른 저장소로 교체 할 수 있다고 생각한다면 말입니다. 실제로는 거의 발생하지 않으며 AppSettings에서 발생할 가능성은 거의 없습니다.
Robert Harvey

10
"getter"는 지능적으로 작동한다는 장점이 있습니다. 키 문자열 "mySetting"(컴파일러가 올바로 작성하면 검사되지 않음)은 한 곳에만 있습니다.
Doc Brown

답변:


5

괜찮아요 클린 코드 (Clean Code) 책에 따르면 실제로 이것은 매우 좋은 습관이며, 밥 아저씨가 실제로 권장합니다. 많은 방법들이 사용하는 변수는 방법들 사이에 높은 응집력을 보여줄 수 있습니다. 또한 높은 수준의 객체 변수는 해당 클래스를 두 개로 나눠야하므로 객체 변수를 선언하면 숨겨진 클래스 후보를 찾는 데 도움이 될 수 있습니다.

객체 레벨 변수는 전역 변수가 아니므로 다양한 방법으로 공유해야하는 경우 사용하는 것을 두려워하지 마십시오.


응집력을 말했을 때 실제로 커플 링을 의미한다고 생각하지만 도움을 주셔서 감사합니다.
user1944367

아니요, 응집력을 의미했습니다. 소프트웨어 엔지니어링 수업에서도 높은 응집력에 대한 욕구를 이해하기가 어려웠습니다. 일반적으로 낮은 커플 링과 높은 응집력으로 정욕합니다. 커플 링은 우리 자신의 방법으로 볼 수있는 물리적 인 것입니다. 클래스가 다른 클래스를 사용하면 클래스가 연결됩니다. 그것이 실제로 상기 클래스의 인스턴스화 및 객체라면, 그것은 그것과 매우 관련이 있습니다. 그러나 응집력은 더 논리적 인 것입니다. 클래스에서 높은 응집력은 메소드가 변수를 공유하지 않더라도 메소드가 매우 유사한 도메인에 속한다는 것을 의미합니다.
Uri

객체 변수를 사용하는 다양한 방법이 반드시 서로 연결된다는 것을 의미하지는 않습니다. char [] 암호 변수를 가진 Encrypter 클래스를 가질 수 있고 Encrypt (string text); 및 해독 (문자열 텍스트); 그 안에 방법. 둘 다 동일한 암호 변수를 사용하지만 그 사이에 명백한 결합은 없습니다. 그러나 동일한 도메인, 즉 텍스트 암호화를 다루는 것을 알 수 있습니다. 내가 아는 한, 그들은 클래스가 두 가지로 나눌 수 있지만 응집력이 높습니다. 암호화가 암호 해독 도메인에 속하지 않는다고 주장 할 수 있습니다.
Uri

4

일정한 방식으로 설정을 캡슐화하는 것이 좋습니다.

내가하는 일은 의존성 주입으로 관리 할 하나의 정적 전역 하나 또는 여러 인스턴스 클래스 중 하나를 설정 클래스로 만드는 것입니다. 그런 다음 시작할 때 구성의 모든 설정을 해당 클래스로로드합니다.

나는 또한 이것을 쉽게하기 위해 리플렉션을 사용하는 작은 라이브러리를 작성했습니다.

설정이 구성 파일에 있으면

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
    <appSettings>
        <add key="Domain" value="example.com" />
        <add key="PagingSize" value="30" />
        <add key="Invalid.C#.Identifier" value="test" />
    </appSettings>
</configuration>

필요에 따라 정적 또는 인스턴스 클래스를 만듭니다. 몇 가지 설정 만있는 간단한 응용 프로그램의 경우 정적 클래스 하나만 있으면됩니다.

private static class Settings
{
    public string Domain { get; set; }

    public int PagingSize { get; set; }

    [Named("Invalid.C#.Identifier")]
    public string ICID { get; set; }

}

그런 다음 라이브러리 호출을 사용 Inflate.Static하거나 Inflate.Instance멋진 것을 사용하면 모든 키 값 소스를 사용할 수 있습니다.

using Fire.Configuration;

Inflate.Static( typeof(Settings), x => ConfigurationManager.AppSettings[x] );

이에 대한 모든 코드는 https://github.com/Enexure/Enexure.Fire.Configuration의 GitHub에 있습니다.

너겟 패키지도 있습니다.

PM> 설치 패키지 Enexure.Fire. 구성

참조 코드 :

using System;
using System.Linq;
using System.Reflection;
using Fire.Extensions;

namespace Fire.Configuration
{
    public static class Inflate
    {
        public static void Static( Type type, Func<string, string> dictionary )
        {
            Fill( null, type, dictionary );
        }

        public static void Instance( object instance, Func<string, string> dictionary )
        {
            Fill( instance, instance.GetType(), dictionary );
        }


        private static void Fill( object instance, Type type, Func<string, string> dictionary ) 
        {

            PropertyInfo[] properties;
            if (instance == null) {

                // Static
                properties = type.GetProperties( BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly );
            } else {

                // Instance
                properties = type.GetProperties( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly );
            }

            // Get app settings and convert
            foreach (PropertyInfo property in properties) {
                var attributes = property.GetCustomAttributes( true );
                if (!attributes.Any( x => x is Ignore )) {

                    var named = attributes.FirstOrDefault( x => x is Named ) as Named;

                    var value = dictionary((named != null)? named.Name : property.Name);

                    object result;
                    if (ExtendConversion.ConvertTo(value, property.PropertyType, out result)) {
                        property.SetValue( instance, result, null );
                    }
                }
            }
        }
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.