C # 'global' değişkenleri nasıl kapsüllenir? /en iyi pratik


9

Birden çok yöntemde kullanmam gereken değişkenleri kapsüllemek için C # en iyi uygulama nedir? Bunları sadece sınıfımın en üstünde iki yöntemin üzerinde bildirmek uygun mudur?

Ayrıca yapılandırma dosyamdan uygulama ayarlarını kullanıyorsanız bir alıcı kullanmalı mıyım? bunun gibi...

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

En iyi uygulama nedir?


Ek bir (ve muhtemelen gereksiz) bir dolaylama katmanı eklemek dışında, bir alıcısının amacı ne olabilir?
Robert Harvey

4
Bir alıcı birden fazla çağrıdan çok daha iyi WebConfigurationManager.AppSettingsçünkü daha sonra değiştirmek çok daha kolay
Daniel Little

@Lavinski: Elbette, veri deposunu daha sonra başka bir veri deposuyla değiştirebileceğinizi düşünüyorsanız. Pratikte, bu nadiren olur ve AppSettings için gerçekleşme olasılığı kaybolan küçüktür.
Robert Harvey

10
Bir "alıcı" akıllı çalışma yapar avantajı vardır - ve sadece bir yerde "mySetting" anahtar dizesi var (doğru yazılmış ise derleyici tarafından kontrol edilmez).
Doc Brown

Yanıtlar:


5

Sadece sorun değil. Temiz Kod kitabına göre bu aslında çok iyi bir uygulamadır ve Bob Amca bunu gerçekten teşvik eder. Birçok yöntem tarafından kullanılan bir değişken, yöntemler arasında yüksek derecede bir uyum gösterebilir. Dahası, yüksek derecede nesne değişkenleri, söz konusu sınıfın ikiye bölünmesi gerektiğini de ima edebilir, böylece bunları nesne değişkenleri olarak bildirmek gizli sınıf adaylarını bulmanıza yardımcı olabilir.

Nesne düzeyindeki değişkenler genel değişken değildir, bu nedenle çeşitli yöntemlerle paylaşılması gerekiyorsa bunları kullanmaktan korkmayın.


yardımlarınız için teşekkürler, ama uyum dediğinde gerçekten birleştirme demek istediğini düşünüyorum.
user1944367

Hayır, uyum demek istedim. Yazılım Mühendisliği dersinde de yüksek uyum arzusunu anlamakta zorlandım. Genellikle düşük kuplaj ve yüksek kohezyondan sonra şehvet duyarız. Eşleştirme, kendi yöntemlerimizde görebildiğimiz fiziksel bir şeydir. Bir sınıf başka bir sınıf kullanıyorsa, sınıfla birleştirilir. Eğer aslında söz konusu sınıfın örneğini ve nesnesini başlatırsa, o zaman ona çok çifttir. Ancak, uyum daha mantıklı bir şeydir. Bir sınıfta yüksek uyum, aralarında herhangi bir değişken paylaşmasalar bile yöntemlerinin çok benzer bir alana ait olduğu anlamına gelir.
Uri

Bir nesne değişkeni kullanan çeşitli yöntemler, bunların birlikte bağlandığı anlamına gelmez. Bir char [] şifre değişkeni ile bir Encrypter sınıfı olabilir ve Encrypt (dize metni) var; ve Decrypt (dize metni); içindeki yöntemler. Her ikisi de aynı şifre değişkenini kullanır, ancak aralarında belirgin bir bağlantı yoktur. Ancak, aynı alanla ve yani metin şifrelemeyle ilgilendiklerini fark edebilirsiniz. Bildiğim kadarıyla, söz konusu sınıf ikiye bölünebilse de, yüksek derecede bir kohezyona sahiptirler. Şifrelemenin şifre çözme alanına ait olmadığı iddia edilebilir.
Uri

4

Ayarlarınızı sabit bir şekilde kapsüllemek harika bir fikirdir.

Ne bir bağımlılık enjeksiyon ile yöneteceğim bir statik küresel bir veya birden çok örnek sınıfları bir ayarlar sınıfı oluşturmaktır. Sonra başlangıçta yapılandırmadan tüm ayarları bu sınıfa yüklerim.

Ayrıca bunu daha da kolaylaştırmak için yansımayı kullanan küçük bir kütüphane yazdım.

Ayarlarım yapılandırma dosyamda olduğunda

<?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>

Benim ihtiyaçlarına bağlı olarak bir statik veya örnek sınıf yapmak. Sadece birkaç ayara sahip basit uygulamalar için bir statik sınıf iyidir.

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

    public int PagingSize { get; set; }

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

}

Sonra benim kütüphane çağrısı ya Inflate.Staticya Inflate.Instanceve serin şey kullanarak herhangi bir anahtar değeri kaynağı kullanabilirsiniz.

using Fire.Configuration;

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

Bunun için tüm kod GitHub'da https://github.com/Enexure/Enexure.Fire.Configuration adresinde bulunmaktadır.

Bir nuget paketi bile var:

PM> Install-Package Enexure.Fire.Configuration

Referans kodu:

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 );
                    }
                }
            }
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.