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.