C # 'da fabrika deseni: Bir nesne örneğinin yalnızca bir fabrika sınıfı tarafından oluşturulabileceğinden nasıl emin olunur?


94

Son zamanlarda kodumun bir kısmını güvenli hale getirmeyi düşünüyordum. Bir nesnenin hiçbir zaman doğrudan yaratılamayacağından, ancak sadece fabrika sınıfının bir yöntemi aracılığıyla nasıl emin olunabileceğini merak ediyorum. Diyelim ki bir "iş nesnesi" sınıfım var ve bu sınıfın herhangi bir örneğinin geçerli bir dahili duruma sahip olduğundan emin olmak istiyorum. Bunu başarmak için, bir nesne oluşturmadan önce, muhtemelen yapıcısında bazı kontroller yapmam gerekecek. Bu kontrolün iş mantığının bir parçası olmasını istediğime karar verene kadar sorun değil. Öyleyse, bir iş nesnesinin yalnızca iş mantığı sınıfımdaki bazı yöntemlerle, ancak asla doğrudan yaratılamaz olmasını nasıl ayarlayabilirim? C ++ 'nın eski güzel bir "arkadaş" anahtar kelimesini kullanmak için ilk doğal arzu C # ile yetersiz kalacaktır. Bu yüzden başka seçeneklere ihtiyacımız var ...

Bir örnek deneyelim:

public MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    public MyBusinessObjectClass (string myProperty)
    {
        MyProperty = myProperty;
    }
}

public MyBusinessLogicClass
{
    public MyBusinessObjectClass CreateBusinessObject (string myProperty)
    {
        // Perform some check on myProperty

        if (true /* check is okay */)
            return new MyBusinessObjectClass (myProperty);

        return null;
    }
}

Girdiyi kontrol etmeden MyBusinessObjectClass örneğini doğrudan oluşturabileceğinizi hatırlayana kadar her şey yolunda. Bu teknik olasılığı tamamen dışlamak istiyorum.

Peki, toplum bu konuda ne düşünüyor?


MyBoClass yöntemi yanlış mı yazılmış?
pradeeptp

2
Kafam karıştı, neden iş nesnelerinizin kendi değişmezlerini korumaktan sorumlu olanlar olmasını istemezsiniz? Fabrika modelinin amacı (anladığım kadarıyla) ya A) birçok bağımlılığa sahip karmaşık bir sınıfın yaratılmasıyla uğraşmak ya da B) fabrikanın hangi çalışma zamanı türünün döndürüleceğine karar vermesine izin vermek, yalnızca bir arabirimi / özeti açığa çıkarmaktır. müşteriye sınıf. İş kurallarınızı iş nesnelerinize koymak, OOP'nin özüdür.
sara

@kai Doğru, iş nesnesi değişmezliğini korumaktan sorumludur, ancak kurucu arayan, argümanların yapıcıya aktarılmadan önce geçerli olduğundan emin olmaktır ! AmacıCreateBusinessObjectYöntemin arayan bağımsız değişkenlerin yapıcıya geçmek için geçerli olup olmadığını hemen bilmediğinde, tek bir yöntem çağrısında VE'ye (yeni bir geçerli nesne döndürmek VEYA bir hata döndürmek) bağımsız değişkenleri doğrulamaktır.
Lighmtan

2
Katılmıyorum. Oluşturucu, verilen parametreler için gerekli tüm kontrolleri yapmaktan sorumludur. Bir kurucu çağırırsam ve bir istisna atılmazsa, oluşturulan nesnenin geçerli bir durumda olduğuna güvenirim. "Yanlış" argümanlar kullanarak bir sınıfın somutlaştırılması fiziksel olarak mümkün olmamalıdır. DistanceNegatif argüman içeren bir örnek oluşturmak, örneğin bir örnek atmalıdır , aynı kontrolü yapan ArgumentOutOfRangeExceptionbir örnek oluşturmaktan hiçbir şey elde edemezsiniz DistanceFactory. Hala burada ne kazanmayı düşündüğünü anlamıyorum.
sara

Yanıtlar:


55

Görünüşe göre, nesneyi oluşturmadan önce biraz iş mantığı çalıştırmak istiyorsunuz - öyleyse neden "BusinessClass" içinde tüm kirli "myProperty" denetimini yapan ve kurucuyu özel yapan statik bir yöntem oluşturmuyorsunuz?

public BusinessClass
{
    public string MyProperty { get; private set; }

    private BusinessClass()
    {
    }

    private BusinessClass(string myProperty)
    {
        MyProperty = myProperty;
    }

    public static BusinessClass CreateObject(string myProperty)
    {
        // Perform some check on myProperty

        if (/* all ok */)
            return new BusinessClass(myProperty);

        return null;
    }
}

Bunu aramak oldukça basit olurdu:

BusinessClass objBusiness = BusinessClass.CreateObject(someProperty);

6
Ah, boş döndürmek yerine bir istisna da atabilirsiniz.
Ricardo Nolde

5
Özel bir tane bildirdiyseniz, özel bir varsayılan kurucuya sahip olmanın bir anlamı yoktur. ayrıca, bu durumda gerçek kurucuda doğrulamayı yapmak yerine statik bir "kurucu" kullanarak elde edilecek hiçbir şey yoktur (zaten sınıfın bir parçası olduğu için). Hatta KÖTÜ, çünkü artık NRE'ler için açılan boş bir dönüş değeri elde edebilirsiniz ve "bu boş değer ne anlama geliyor?" sorular.
sara

Bu mimariyi bir Arayüz / soyut temel sınıf aracılığıyla gerektirmenin iyi bir yolu var mı? yani, uygulayıcıların bir ctoru açığa çıkarmamasını dikte eden bir arayüz / soyut temel sınıf.
Arash Motamedi

1
@Arash Hayır. Arabirimler kurucuları tanımlayamaz ve korumalı veya dahili bir oluşturucuyu tanımlayan soyut bir sınıf, sınıfların miras alınmasını kendi genel bir oluşturucusu aracılığıyla göstermesini engelleyemez.
Ricardo Nolde

67

Yapıcıyı özel ve fabrikayı iç içe bir tür yapabilirsiniz:

public class BusinessObject
{
    private BusinessObject(string property)
    {
    }

    public class Factory
    {
        public static BusinessObject CreateBusinessObject(string property)
        {
            return new BusinessObject(property);
        }
    }
}

Bu işe yarar çünkü yuvalanmış türlerin, kendi çevreleyen türlerinin özel üyelerine erişimi vardır. Biraz kısıtlayıcı olduğunu biliyorum ama umarım yardımcı olur ...


Bunu düşündüm, ancak bu çekleri etkili bir şekilde kaçınmaya çalıştığım iş nesnesinin kendisine taşıyor.
Kullanıcı

@ so-tester: Kontrolleri BusinessObject türü yerine fabrikada yine de alabilirsiniz.
Jon Skeet

3
@JonSkeet Bu sorunun gerçekten eski olduğunu biliyorum, ancak bu statik yöntemin doğrudan sınıfın bir yöntemi olması yerine CreateBusinessObjectyöntemi iç içe geçmiş bir Factorysınıfın içine yerleştirmenin avantajının ne olduğunu merak ediyorum BusinessObject... bunu yapmak için motivasyon?
Kiley Naro

3
@KileyNaro: Sorunun sorulduğu şey buydu :) Pek çok avantaj sağlamıyor, ama soruyu cevaplıyor ... bunun faydalı olduğu zamanlar da olabilir - inşaatçı modeli akla gelir. (Bu durumda, oluşturucu iç içe geçmiş sınıf olacaktır ve adı verilen bir örnek yöntemi olacaktır Build.)
Jon Skeet

53

Ya da, gerçekten süslü olmak istiyorsanız, kontrolü tersine çevirin: Sınıfın fabrikayı geri göndermesini ve fabrikayı, sınıfı yaratabilecek bir temsilciyle donatmasını sağlayın.

public class BusinessObject
{
  public static BusinessObjectFactory GetFactory()
  {
    return new BusinessObjectFactory (p => new BusinessObject (p));
  }

  private BusinessObject(string property)
  {
  }
}

public class BusinessObjectFactory
{
  private Func<string, BusinessObject> _ctorCaller;

  public BusinessObjectFactory (Func<string, BusinessObject> ctorCaller)
  {
    _ctorCaller = ctorCaller;
  }

  public BusinessObject CreateBusinessObject(string myProperty)
  {
    if (...)
      return _ctorCaller (myProperty);
    else
      return null;
  }
}

:)


Çok güzel bir kod parçası. Nesne oluşturma mantığı ayrı bir sınıftadır ve nesne yalnızca fabrika kullanılarak oluşturulabilir.
Nikolai Samteladze

Güzel. BusinessObjectFactory'nin oluşturulmasını statik BusinessObject.GetFactory ile sınırlandırmanın bir yolu var mı?
Felix Keil

1
Bu ters çevirmenin avantajı nedir?
yatskovsky

1
@yatskovsky Nesnenin yalnızca kontrollü bir şekilde somutlaştırılabilmesini sağlamanın bir yolu ve yine de yaratma mantığını özel bir sınıfa dahil edebilir.
Fabian Schmied

15

MyBusinessObjectClass sınıfınızdaki kurucuyu dahili yapabilir ve onu ve fabrikayı kendi derlemelerine taşıyabilirsiniz. Artık sınıfın bir örneğini yalnızca fabrika oluşturabilmelidir.


7

Jon'un önerdiğinin yanı sıra, fabrika yöntemini (kontrol dahil) ilk etapta BusinessObject'in statik bir yöntemi olabilir. Ardından, kurucuyu özel yapın ve diğer herkes statik yöntemi kullanmaya zorlanacaktır.

public class BusinessObject
{
  public static Create (string myProperty)
  {
    if (...)
      return new BusinessObject (myProperty);
    else
      return null;
  }
}

Ama asıl soru şu - neden bu şarta sahipsiniz? Fabrika veya fabrika yöntemini sınıfa taşımak kabul edilebilir mi?


Bu bir gereklilik değildir. Sadece iş nesnesi ile mantığın temiz bir şekilde ayrılmasını istiyorum. Bu kontrollerin sayfaların arkasındaki kodda olması uygunsuz olduğu gibi, bu kontrollerin nesnelerin kendisinde olmasını uygun bulmuyorum. Belki temel doğrulama, ama gerçekten iş kuralları değil.
Kullanıcı

Bir sınıfın mantığını ve yapısını yalnızca uygunluğu gözden geçirmek için ayırmak istiyorsanız, her zaman kısmi bir sınıf kullanabilir ve her ikisini de ayrı dosyalarda bulundurabilirsiniz ...
Grx70

7

Yıllar sonra bu soruldu ve gördüğüm tüm cevaplar maalesef size doğrudan bir cevap vermek yerine kodunuzu nasıl yapmanız gerektiğini söylüyor. Aradığınız asıl cevap, sınıflarınızın özel bir kurucu, ancak genel bir anlık oluşturucuya sahip olmasıdır; bu, yalnızca diğer mevcut örneklerden yeni örnekler oluşturabileceğiniz anlamına gelir ... yalnızca fabrikada mevcuttur:

Sınıflarınız için arayüz:

public interface FactoryObject
{
    FactoryObject Instantiate();
}

Senin sınıfın:

public class YourClass : FactoryObject
{
    static YourClass()
    {
        Factory.RegisterType(new YourClass());
    }

    private YourClass() {}

    FactoryObject FactoryObject.Instantiate()
    {
        return new YourClass();
    }
}

Ve nihayet fabrika:

public static class Factory
{
    private static List<FactoryObject> knownObjects = new List<FactoryObject>();

    public static void RegisterType(FactoryObject obj)
    {
        knownObjects.Add(obj);
    }

    public static T Instantiate<T>() where T : FactoryObject
    {
        var knownObject = knownObjects.Where(x => x.GetType() == typeof(T));
        return (T)knownObject.Instantiate();
    }
}

Ardından, örnekleme için ekstra parametrelere ihtiyacınız varsa veya oluşturduğunuz örnekleri önceden işlemek için bu kodu kolayca değiştirebilirsiniz. Ve bu kod, sınıf oluşturucu özel olduğu için fabrika üzerinden başlatmayı zorlamanıza izin verecektir.


4

Diğer bir (hafif) seçenek ise BusinessObject sınıfında statik bir fabrika yöntemi yapmak ve yapıcıyı özel tutmaktır.

public class BusinessObject
{
    public static BusinessObject NewBusinessObject(string property)
    {
        return new BusinessObject();
    }

    private BusinessObject()
    {
    }
}

2

Yani, istediğim şey "saf" bir şekilde yapılamaz gibi görünüyor. Mantık sınıfına her zaman bir tür "geri arama" dır.

Belki bunu basit bir şekilde yapabilirim, sadece nesne sınıfında bir yapıcı yöntemi yapın, önce girişi kontrol etmek için mantık sınıfını çağırın?

public MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    private MyBusinessObjectClass (string myProperty)
    {
        MyProperty  = myProperty;
    }

    pubilc static MyBusinessObjectClass CreateInstance (string myProperty)
    {
        if (MyBusinessLogicClass.ValidateBusinessObject (myProperty)) return new MyBusinessObjectClass (myProperty);

        return null;
    }
}

public MyBusinessLogicClass
{
    public static bool ValidateBusinessObject (string myProperty)
    {
        // Perform some check on myProperty

        return CheckResult;
    }
}

Bu şekilde, iş nesnesi doğrudan oluşturulamaz ve iş mantığındaki genel kontrol yöntemi de zarar vermez.


2

Arayüzler ve uygulamalar arasında iyi bir ayrım olması durumunda,
korumalı-yapıcı-genel-başlatıcı modeli çok düzgün bir çözüme izin verir.

Bir iş nesnesi verildiğinde:

public interface IBusinessObject { }

class BusinessObject : IBusinessObject
{
    public static IBusinessObject New() 
    {
        return new BusinessObject();
    }

    protected BusinessObject() 
    { ... }
}

ve bir iş fabrikası:

public interface IBusinessFactory { }

class BusinessFactory : IBusinessFactory
{
    public static IBusinessFactory New() 
    {
        return new BusinessFactory();
    }

    protected BusinessFactory() 
    { ... }
}

BusinessObject.New()Başlatıcıda yapılan aşağıdaki değişiklik çözümü verir:

class BusinessObject : IBusinessObject
{
    public static IBusinessObject New(BusinessFactory factory) 
    { ... }

    ...
}

Burada, BusinessObject.New()başlatıcıyı aramak için somut iş fabrikasına bir referans gereklidir . Ancak gerekli referansa sahip olan tek kişi iş fabrikasının kendisidir.

Oluşturabilir tek: Biz istediğini aldı BusinessObjectolduğunu BusinessFactory.


Yani, nesnenin çalışan tek genel kurucusunun bir Factory gerektirdiğinden ve gerekli olan Factory parametresinin yalnızca Factory'nin statik yöntemini çağırarak somutlaştırılabileceğinden emin misiniz? Çalışan bir çözüm gibi görünüyor, ancak public static IBusinessObject New(BusinessFactory factory) kodun başka biri tarafından korunduğu takdirde, benzer parçacıkların çok fazla kaşınacağı hissine kapılıyorum .
flater

@Düz Kabul Edildi. Parametre adını factoryolarak değiştirirdim asFriend. Kod public static IBusinessObject New(BusinessFactory asFriend)
Reuven Bass

Ben hiç anlamadım. O nasıl çalışır? Fabrika, IBusinessObject'in yeni örneklerini oluşturamaz veya bunu yapmak için herhangi bir niyeti (yöntemi) yoktur ...?
lapsus

2
    public class HandlerFactory: Handler
    {
        public IHandler GetHandler()
        {
            return base.CreateMe();
        }
    }

    public interface IHandler
    {
        void DoWork();
    }

    public class Handler : IHandler
    {
        public void DoWork()
        {
            Console.WriteLine("hander doing work");
        }

        protected IHandler CreateMe()
        {
            return new Handler();
        }

        protected Handler(){}
    }

    public static void Main(string[] args)
    {
        // Handler handler = new Handler();         - this will error out!
        var factory = new HandlerFactory();
        var handler = factory.GetHandler();

        handler.DoWork();           // this works!
    }

Lütfen yaklaşımımı deneyin, 'fabrika' işleyicinin kapsayıcısıdır ve sadece kendisi için bir örnek oluşturabilir. bazı değişikliklerle ihtiyaçlarınızı karşılayabilir.
lin

1
Örneğinizde, aşağıdakiler mümkün olmaz mıydı (bu mantıklı olmaz) ?: factory.DoWork ();
Whyser

1

Fabrikayı etki alanı sınıfıyla aynı derlemeye koyar ve etki alanı sınıfının yapıcısını dahili olarak işaretlerdim. Bu şekilde, alanınızdaki herhangi bir sınıf bir örnek oluşturabilir, ancak kendinize güvenmiyorsunuz, değil mi? Etki alanı katmanı dışında kod yazan herkes fabrikanızı kullanmak zorunda kalacaktır.

public class Person
{
  internal Person()
  {
  }
}

public class PersonFactory
{
  public Person Create()
  {
    return new Person();
  }  
}

Ancak, yaklaşımınızı sorgulamalıyım :-)

Person sınıfınızın yaratılırken geçerli olmasını istiyorsanız, kodu kurucuya koymanız gerektiğini düşünüyorum.

public class Person
{
  public Person(string firstName, string lastName)
  {
    FirstName = firstName;
    LastName = lastName;
    Validate();
  }
}


1

Farklı ödünleşimlere sahip çoklu yaklaşımlardan bahsedilmiştir.

  • Fabrika sınıfını özel olarak inşa edilen sınıfa yerleştirmek, fabrikanın yalnızca 1 sınıf oluşturmasına izin verir. Bu noktada bir Createyöntem ve özel bir hocayla daha iyi durumda olursunuz .
  • Miras ve korumalı bir ctor kullanmak da aynı soruna sahiptir.

Fabrikayı, genel oluşturuculara sahip özel yuvalanmış sınıfları içeren kısmi bir sınıf olarak önermek istiyorum. Fabrikanızın inşa ettiği nesneyi% 100 gizliyorsunuz ve yalnızca bir veya daha fazla arayüz aracılığıyla seçtiğiniz şeyi açığa çıkarıyorsunuz.

Bunun için duyduğum kullanım örneği, fabrikadaki örneklerin% 100'ünü izlemek istediğinizde olacaktır. Bu tasarım, fabrikanın "fabrikada" tanımlanan "kimyasallar" örneklerini oluşturmaya erişimi dışında kimseyi garanti etmez ve bunu başarmak için ayrı bir montaj ihtiyacını ortadan kaldırır.

== ChemicalFactory.cs ==
partial class ChemicalFactory {
    private  ChemicalFactory() {}

    public interface IChemical {
        int AtomicNumber { get; }
    }

    public static IChemical CreateOxygen() {
        return new Oxygen();
    }
}


== Oxygen.cs ==
partial class ChemicalFactory {
    private class Oxygen : IChemical {
        public Oxygen() {
            AtomicNumber = 8;
        }
        public int AtomicNumber { get; }
    }
}



== Program.cs ==
class Program {
    static void Main(string[] args) {
        var ox = ChemicalFactory.CreateOxygen();
        Console.WriteLine(ox.AtomicNumber);
    }
}

0

Neden "iş mantığını" "iş nesnesi" nden ayırmak istediğinizi anlamıyorum. Bu, nesne yöneliminde bir bozulma gibi geliyor ve bu yaklaşımı benimseyerek kendinizi düğümlere bağlamış olacaksınız.


Ben de bu ayrımı anlamıyorum. Birisi bunun neden yapıldığını ve iş nesnesinde hangi kodun olacağını açıklayabilir mi?
pipTheGeek

Kullanılabilecek yaklaşımlardan sadece biri. İş nesnesinin esas olarak veri yapıları olmasını istiyorum, ancak tüm alan okuma / yazma için açık değil. Ancak asıl soru, doğrudan doğruya değil, yalnızca bir fabrika yöntemi yardımıyla bir nesneyi somutlaştırabilmekle ilgiliydi.
Kullanıcı

@Jim: Ben senin fikrine kişisel olarak katılıyorum ama profesyonel olarak bu sürekli yapılıyor. Mevcut projem, bir HTML dizesi alan, onu bazı önceden belirlenmiş kurallara göre temizleyen ve ardından temizlenmiş dizeyi döndüren bir web hizmetidir. Kendi kodumun 7 katmanından geçmem gerekiyor "çünkü tüm projelerimiz aynı proje şablonundan inşa edilmelidir". SO'da bu soruları soran çoğu insanın kodlarının tüm akışını değiştirme özgürlüğüne sahip olmaması mantıklıdır.
flater

0

Sorundan daha kötü olmayan bir çözüm olduğunu sanmıyorum, yukarıda belirtilenlerin tümü, IMHO'nun daha kötü bir sorun olduğu ve insanların sadece fabrikayı nesnenizi kullanmaları için çağırmasını engellemeyecek bir kamu statik fabrikasına ihtiyaç duyuyor - hiçbir şeyi gizlemiyor. Bir arabirimi ortaya çıkarmak ve / veya yapıcıyı yapabiliyorsanız dahili olarak tutmak en iyisidir, bu, derleme güvenilir kod olduğundan en iyi korumadır.

Bir seçenek, bir fabrikayı IOC konteyneri gibi bir yere kaydeden statik bir kurucuya sahip olmaktır.


0

İşte "sırf yapabilmen, yapman gerektiği anlamına gelmez" damarındaki başka bir çözüm ...

İş nesnesi kurucusunu özel tutma ve fabrika mantığını başka bir sınıfa koyma gereksinimlerini karşılar. Bundan sonra biraz kabataslak oluyor.

Factory sınıfı, iş nesneleri oluşturmak için statik bir yönteme sahiptir. Özel oluşturucuyu çağıran statik korumalı bir yapı yöntemine erişmek için iş nesnesi sınıfından türetilir.

Fabrika soyut olduğundan bir örneğini gerçekten oluşturamazsınız (çünkü aynı zamanda bir iş nesnesi olurdu, bu yüzden tuhaf olurdu) ve özel bir kurucuya sahiptir, böylece müşteri kodu ondan türetilemez.

Engellenmeyen şey, istemci kodunun da iş nesnesi sınıfından türetilmesi ve korumalı (ancak doğrulanmamış) statik yapı yöntemini çağırmasıdır. Daha da kötüsü, fabrika sınıfının ilk etapta derlenmesini sağlamak için eklememiz gereken korumalı varsayılan kurucuyu çağırmak. (Tesadüfen, fabrika sınıfını iş nesnesi sınıfından ayıran herhangi bir modelde bir sorun olması muhtemeldir.)

Aklı başında kimseye böyle bir şey yapmasını önermeye çalışmıyorum, ama bu ilginç bir egzersizdi. FWIW, benim tercih ettiğim çözüm, dahili bir kurucu ve koruma olarak montaj sınırını kullanmak olacaktır.

using System;

public class MyBusinessObjectClass
{
    public string MyProperty { get; private set; }

    private MyBusinessObjectClass(string myProperty)
    {
        MyProperty = myProperty;
    }

    // Need accesible default constructor, or else MyBusinessObjectFactory declaration will generate:
    // error CS0122: 'MyBusinessObjectClass.MyBusinessObjectClass(string)' is inaccessible due to its protection level
    protected MyBusinessObjectClass()
    {
    }

    protected static MyBusinessObjectClass Construct(string myProperty)
    {
        return new MyBusinessObjectClass(myProperty);
    }
}

public abstract class MyBusinessObjectFactory : MyBusinessObjectClass
{
    public static MyBusinessObjectClass CreateBusinessObject(string myProperty)
    {
        // Perform some check on myProperty

        if (true /* check is okay */)
            return Construct(myProperty);

        return null;
    }

    private MyBusinessObjectFactory()
    {
    }
}

0

Bu çözüm hakkında bazı düşünceler duymak isterim. 'MyClassPrivilegeKey' yaratabilen tek şey fabrikadır. ve 'MyClass' yapıcıda gerektirir. Böylelikle özel yükleniciler / fabrikaya "kayıt" üzerine yansımadan kaçınılmış olur.

public static class Runnable
{
    public static void Run()
    {
        MyClass myClass = MyClassPrivilegeKey.MyClassFactory.GetInstance();
    }
}

public abstract class MyClass
{
    public MyClass(MyClassPrivilegeKey key) { }
}

public class MyClassA : MyClass
{
    public MyClassA(MyClassPrivilegeKey key) : base(key) { }
}

public class MyClassB : MyClass
{
    public MyClassB(MyClassPrivilegeKey key) : base(key) { }
}


public class MyClassPrivilegeKey
{
    private MyClassPrivilegeKey()
    {
    }

    public static class MyClassFactory
    {
        private static MyClassPrivilegeKey key = new MyClassPrivilegeKey();

        public static MyClass GetInstance()
        {
            if (/* some things == */true)
            {
                return new MyClassA(key);
            }
            else
            {
                return new MyClassB(key);
            }
        }
    }
}
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.