Soru Statik fabrika yöntemleri nelerdir?


"Statik fabrika" yöntemi nedir?


207
2018-05-30 04:46


Menşei


Alternatif statik fabrika yöntemleri bağımlılık enjeksiyonunu kullanıyor. - CMCDragonkai
@ThangPham Jason Owen'in cevabı kusurludur çünkü bu, gerçekte hakkında konuştuğu statik fabrika yönteminden çok farklı olan Factory Method modelinden bahseder. Bu yüzden, asıl soruyu cevaplamak için iyi bir iş çıkarsa da, onun şu anki haliyle kabul edilebileceğini düşünmüyorum, çünkü ilgisiz bir örüntüyü beraberinde getiriyor ve iki model arasındaki fark hakkında zaten inanılmaz derecede yaygın olan karışıklığı arttırıyor. - Theodore Murdock
@CMCDragonkai Ben bağımlılık enjeksiyon ve statik fabrika farklı olduğunu düşünüyorum. Bağımlılıkların enjekte edilmesi için bağımlılık enjeksiyonu durumunda bile statik fabrika gerekli olabilir. - Karan Khanna


Cevaplar:


Kaynak yoğun olduğu için veritabanı bağlantılarına doğrudan erişim sağlamaktan kaçınıyoruz. Bu yüzden statik bir fabrika yöntemi kullanıyoruz getDbConnection sınırın altında olmamız durumunda bir bağlantı oluşturur. Aksi halde, "yedek" bir bağlantı sağlamaya çalışır, hiçbiri yoksa bir istisna ile başarısız olur.

public class DbConnection{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection(){
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection(){

     if(totalConnections < MAX_CONNS){
       return new DbConnection();

     }else if(availableConnections.size() > 0){
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;

     }else {
         throw new NoDbConnections();
     }
   }

   public static void returnDbConnection(DbConnection dbc){
     availableConnections.add(dbc);
     //...
   }
}

94
2018-05-30 05:04



doğru anlarsam, availableConnections.add (db) yöntemine returnDbConnection (DbConnection db) yöntemini ekleyebilir misiniz? - Haifeng Zhang
@haifzhan, gerçekten tamamlanmış değil, tamam. - Matthew Flaschen
@MatthewFlaschen ayrıca bağlantı geri döndüğünde totalConnections azaltılmalı mı? - Sridhar
@Sridhar, hayır, var olan bağlantıların sayısı (izlenen MAX_CONNS değerinden fazla değil), dolaşımdaki sayı değil. - Matthew Flaschen


statik fabrika metodu modeli nesne oluşturmayı kapsüllemek için bir yoldur. Bir fabrika yöntemi olmadan, sadece sınıfın adını inşaatçı direkt olarak: Foo x = new Foo(). Bu modelle, fabrika yöntemini çağırırsınız: Foo x = Foo.create(). Kurucular özel olarak işaretlenmiştir, bu nedenle sınıfın içinden hariç çağrılmazlar ve fabrika yöntemi şu şekilde işaretlenir: static Böylece ilk önce bir nesneye sahip olmadan çağrılabilir.

Bu desene birkaç avantaj var. Birincisi, fabrikanın birçok alt sınıftan (veya bir arayüzün uygulayıcılarından) birini seçebiliyor ve buna geri dönebiliyor. Bu şekilde, arayan, potansiyel olarak karmaşık bir sınıf hiyerarşisini bilmeye veya anlamaya gerek kalmaksızın, parametreler yoluyla istenen davranışı belirleyebilir.

Başka bir avantaj, Matthew ve James'in işaret ettiği gibi, bağlantılar gibi sınırlı bir kaynağa erişimi kontrol etmektir. Bunu uygulamak için bir yol yeniden kullanılabilir nesneler havuzları - Bir nesneyi kurmak, kullanmak ve yıkmak yerine, eğer inşaat ve imha pahalı süreçler ise, bunları bir kez inşa etmek ve geri dönüştürmek daha mantıklı olabilir. Fabrika yöntemi, mevcutsa, kullanılmayan, anlık nesneye sahipse veya nesne sayısı bir alt eşiğin altındaysa veya bir istisna veya geri dönüşü varsa null Üst eşiğin üstünde ise.

Wikipedia'daki makaleye göre, birden fazla fabrika yöntemi de benzer argüman türlerinin farklı yorumlanmasına izin vermektedir. Normalde kurucu, sınıfla aynı ada sahiptir, bu da verili bir kurucunuzun olabileceği anlamına gelir. imza. Fabrikalar bu kadar kısıtlı değildir, yani aynı argüman türlerini kabul eden iki farklı yönteme sahip olabilirsiniz:

Coordinate c = Coordinate.createFromCartesian(double x, double y)

ve

Coordinate c = Coordinate.createFromPolar(double distance, double angle)

Bu, Rasmus'ın da belirttiği gibi okunabilirliği geliştirmek için de kullanılabilir.


422
2018-05-30 07:44



Statik bir fabrika yönteminin, Tasarım Kalıpları'ndan Fabrika Yöntemi modeli ile aynı olmadığını unutmayın [Gamma95, s. 107]. Bu öğede açıklanan statik fabrika yönteminin Tasarım Kalıplarında doğrudan eşdeğeri yoktur. - Josh Sunshine
Bu cevapta bana verilen getiri, poolable nesnelerin referansıdır. Bu, fabrika yöntemini nasıl kullandığımı tam olarak. Bir nesnenin yaşam döngüsünü kontrol etmeye yardımcı olmak için fabrika yöntemleri sağlanmıştır: "oluşturma", havuzdan bir nesneyi çeker veya havuz boşsa yeni bir örnek oluşturur; "yok et", gelecekteki yeniden kullanım için havuza geri döner. - MutantXenu
Bu gönderide "fabrika metodu kalıbı" dediğiniz her yerde "statik fabrika metodu kalıbı" kullanıyor olmalısınız, yanlış terimi kullanıyorsunuz. Ayrıca, Wikipedia makalesine, bahsettiğiniz modelden farklı bir desenle bağlantı veriyorsunuz. Fabrika Metodu kalıbı, "Fabrika Arayüzü" kalıbı olarak adlandırılmış olmalıdır, çünkü bir fabrika nesnesinin, bir ara yüzün örnekleriyle birlikte çalışabilmesi için, tek bir algoritmanın üretilmesi için bir fabrika ara yüzünü uygulayan bir fabrika nesnesi kullanılarak yapılmasını gerektirmektedir. Bu istenen belirli alt sınıfı üretebilir. - Theodore Murdock
@TheodoreMurdock ile aynı fikirdeyim. Yanlış terimi kullanıyorsun. Bahsettiğiniz şey, Joshua Bloch'un "Statik Fabrika Metodu", ancak GoF'un "Factory Method Pattern" terimini kullanıyorsunuz. Lütfen yanlış anlaşılmaması gereken diğer kişiler için düzenleyin. - Emerald Hieu
Kurucunun özel olması gerekmediğini unutmayın. Bir sınıf hem kamu statik fabrika yöntemlerini hem de kurucuları sağlayabilir. - Kevin


NOT! " statik fabrika yöntemi olduğu DEĞİL aynı Fabrika Yöntemi desen "(c) Etkili Java, Joshua Bloch.

Fabrika Yöntemi: "Bir nesne oluşturmak için bir arabirim tanımlayın, ancak ara yüzü uygulayan sınıfların, hangi sınıfın başlatılacağına karar vermesine izin verin. Factory yöntemi, bir sınıfın, (c) GoF alt sınıflarına bir sınıf ertelemesine izin verir.

"Statik fabrika yöntemi, bir sınıfın örneğini döndüren basit bir yöntemdir." (c) Etkili Java, Joshua Bloch. Genellikle bu yöntem belirli bir sınıfın içinde.

Fark:

Statik fabrika yönteminin ana fikri, nesne oluşturma üzerinde kontrol sağlamak ve kurucudan statik yönteme devretmektir. Nesnenin yaratılması kararı, yöntemin dışında yapılan Soyut Fabrika'da olduğu gibi (ortak durumda, fakat her zaman değil). Fabrika Metodu'nun anahtar (!) Fikri, Fabrika Örneğinin içinde hangi sınıf örneğinin oluşturulacağına karar vermektir. Örneğin. Klasik Singleton uygulaması, statik fabrika yönteminin özel bir durumudur. Yaygın olarak kullanılan statik fabrika yöntemleri örneği:

  • değeri
  • getInstance
  • newInstance

130
2018-03-28 19:44



NEDEN farkı bilen biri ... - dcastro
Yeni A () ve A.newInstance () arasındaki farkı söyleyebilir misiniz? ve A.NewInstance'ın içinde ne yapmalıyız? - Shen


Okunabilirlik, statik fabrika yöntemleri ile geliştirilebilir:

Karşılaştırmak

public class Foo{
  public Foo(boolean withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

için

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();

64
2018-05-30 06:43



Bu yüzden size örnek oluşturmaya çalıştım ama bunun nasıl çalıştığından emin değilim. İki yöntem, WithBar'ı yaratır ve Foo sınıfındaki 2 özel kurucuyu çağırması içinWithoutBar'ı yaratır mı? - Baxtex
@Baxtex: Evet. Her biri özel bir kurucu arayacak. Belki de sadece aynı olanı: private Foo(boolean withBar){/*..*/}  public static Foo createWithBar(){return new Foo(true);}  public static Foo createWithoutBar(){return new Foo(false);} - Rasmus Faber
Bence bu "ölçek" çok iyi değil. Üç veya daha fazla parametreniz varsa, bu fikri nasıl kullanabileceğinizi ve yöntem için nasıl güzel bir ad oluşturabileceğinizi öğrenin. - Dherik
@Dherik: O zaman muhtemelen bunun yerine oluşturucu desenini kullanmalısınız: yeni FooBuilder (). WithBar (). WithoutFoo (). WithBaz (). Build (); - Rasmus Faber


  • Kodları açıklığa kavuşturabilecek kuruculardan farklı isimlere sahip olmak.
  • Her bir çağrıda yeni bir nesne oluşturmaya gerek yok - nesneler   Gerekirse önbelleğe alınabilir ve yeniden kullanılabilir.
  • dönüş türlerinin alt türlerini döndürebilir - özellikle   Uygulama sınıfı, arayan kişiye bilinmeyen bir nesne döndürür.   Bu, birçok çerçevede çok değerli ve yaygın olarak kullanılan bir özelliktir   Statik fabrika yöntemlerinin dönüş tipi olarak arayüzleri kullanır.

itibarenhttp://www.javapractices.com/topic/TopicAction.do?Id=21


18
2018-05-30 04:52





Her şey sürekliliğe kadar kaynar. Bunu kullanmanın en iyi yolu, her kullandığınızda new Bir nesne oluşturmak için anahtar kelime, bir uygulamaya yazdığınız kodu birleştirirsiniz.

Fabrika kalıbı, nesneyle yaptığınız nesneden nesneyi nasıl oluşturduğunuzu ayırmanızı sağlar. Oluşturucuları kullanarak tüm nesnelerinizi oluşturduğunuzda, aslında bu uygulama için nesneyi kullanan kodun sabit kablolamasıdır. Nesnenizi kullanan kod, bu nesneye "bağlıdır". Bu, yüzeyde çok büyük bir şey gibi görünmeyebilir, ancak nesne değiştiğinde (kurucunun imzasını değiştirmeyi veya nesneyi alt sınıflara ayırmayı düşünün), her yere geri dönüp her şeyi yeniden yazmanız gerekir.

Günümüzde fabrikalar büyük ölçüde Bağımlılık Enjeksiyon kullanma lehine fırçalıyorlardı, çünkü kendini korumak için biraz zor olan bir çok kazan-plaka koduna ihtiyaç duyuyorlar. Bağımlılık Enjeksiyon temel olarak fabrikalara eşdeğerdir, ancak nesnelerin deklarasyonla birlikte nasıl yapılandırılacağını belirlemenize izin verir (yapılandırma veya ek açıklamalarla).


16
2018-05-30 05:30



Fabrikaların kurtarmaya ihtiyacı olduğunu mu söylüyorsun? ;) - jfar
Haha! Bu gün ve yaşta hepimizin kurtarıcı kullanabileceğini düşünüyorum ... :) - cwash


Bir sınıfın kurucusu özel ise o zaman sınıfın dışında bir nesne oluşturamazsınız.

class Test{
 int x, y;
 private Test(){
  .......
  .......
  }
}

Yukarıdaki sınıf için dışarıdan bir nesne oluşturamayız. Yani, sınıfın dışından x, y'ye erişemezsiniz. Öyleyse bu sınıfın kullanımı nedir?
İşte Cevap: FABRİKA yöntem.
Yukarıdaki yöntemi yukarıdaki sınıfa ekleyin

public static Test getObject(){
  return new Test();
}

Yani şimdi bu sınıfın dışında bir nesne yaratabilirsiniz. Yol gibi ...

Test t = Test.getObject();

Bu nedenle, özel yapısını çalıştırarak sınıfın nesnesini döndüren statik bir yöntem olarak adlandırılır. FABRİKA yöntem
.


9
2017-12-05 05:07



Neden buna "çözüm" diyorsun? Özel bir kurucu ilan etmek bir "sorun" değil, bir tasarım deseni. - ojonugwa ochalifu
Güncellenmiş. Yine de teşekkürler - Santhosh


Bildiğim kadarıyla bu yazıya biraz ışık katacağımı düşündüm. Bu tekniği yoğun bir şekilde recent android project. Yerine creating objects using new operator Ayrıca kullanabilirsiniz static method Bir dersi örneklendirmek. Kod listesi:

//instantiating a class using constructor
Vinoth vin = new Vinoth(); 

//instantiating the class using static method
Class Vinoth{
  private Vinoth(){
  }
  // factory method to instantiate the class
  public static Vinoth getInstance(){
    if(someCondition)
        return new Vinoth();
  }
}

Statik yöntemler koşullu nesne oluşturmayı destekler: Bir kurucu çağırdığınızda her zaman bir nesne oluşturulur, ancak bunu istemeyebilirsiniz. sadece yeni bir nesne oluşturmak istediğinizde bazı koşulu kontrol etmek istediğinizi varsayalım. Koşulunuz tatmin olmadıkça, her seferinde yeni bir Vinoth örneği oluşturmayacaksınız.

Alınan başka bir örnek Etkili Java.

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
}

Bu yöntem, bir boolean ilkel değerini bir Boole nesnesi başvurusuna dönüştürür. Boolean.valueOf(boolean) yöntem bize gösterir, asla bir nesne yaratmaz. Yeteneği static factory methods aynı nesneyi tekrardan döndürmek için invocations sınıfların herhangi bir zamanda hangi örneklerin var olduğuna sıkı bir şekilde hakim olmasını sağlar.

Static factory methods öyle değil constructorsbir dönüş yapabilirler object herhangi bir subtype dönüş türlerinden Bu esnekliğin bir uygulaması, bir API'nin nesnelerini herkese açık hale getirmeden nesneleri döndürebilmesidir. Uygulama sınıflarını bu şekilde gizlemek çok kompakt bir API'ye yol açar.

Calendar.getInstance () yukarıdakiler için harika bir örnektir. BuddhistCalendar, JapaneseImperialCalendar veya varsayılan olarak Georgian.

Düşünebildiğim başka bir örnek Singleton pattern, kurucularınızı özel yaptığınız yerde getInstance emin olduğunuz yöntem, her zaman sadece bir örnek mevcuttur.

public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}

8
2017-09-22 19:46





Bir fabrika metodu, bir nesnenin kopyasını soyutlayan bir yöntemdir. Genellikle fabrikalar, bazı arabirimleri uygulayan bir sınıfın yeni bir örneğine gereksinim duyduğunuzu bildiğinizde yararlıdır, ancak uygulama sınıfını bilmiyorsunuzdur.

Bu, ilgili sınıfların hiyerarşileri ile çalışırken yararlıdır, bunun iyi bir örneği bir GUI araç takımı olacaktır. Her bir parçacığın somut uygulamaları için yapıcılara çağrıları zorla kodlayabiliyordunuz, ancak bir araç setini bir diğeriyle değiştirmek istediğinizde değişecek çok yeriniz olacak. Bir fabrika kullanarak, değiştirmeniz gereken kod miktarını azaltırsınız.


3
2018-05-30 04:51



Fabrikanızın varsayarak ele aldığınız beton sınıfını değil, bir arabirim türü döndürdüğünü varsayalım. - Bill Lynch
Bu cevap hakkında fabrika yöntemi tasarım deseni statik fabrika yöntemleri değil. Statik bir fabrika yöntemleri, bir sınıfın örneğini döndüren basit bir statik yöntemdir. Daha fazla ayrıntı için Etkili Java'nın 2. Bölümüne bakın. - Josh Sunshine


Statik fabrikadan kaynaklanan avantajlardan biri, API'nin sınıflarını kamuya açık hale getirmeksizin nesneleri iade edebilmesidir. Bu çok kompakt bir API'ye yol açar. Java'da bu toplama koleksiyon API'sı çok kompakt hale getiren 32 dersi saklayan Koleksiyonlar sınıfı tarafından gerçekleştirilir.


3
2017-10-04 17:33