"Statik fabrika" yöntemi nedir?
"Statik fabrika" yöntemi nedir?
Yanıtlar:
Kaynak yoğun oldukları için veritabanı bağlantılarına doğrudan erişim sağlamaktan kaçınırız. Bu nedenle getDbConnection
, sınırın altında olduğumuzda bağlantı oluşturan statik bir fabrika yöntemi kullanıyoruz . Aksi takdirde, "yedek" bir bağlantı sağlamaya çalışır, 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);
//...
}
}
Statik fabrika yöntemi desen kapsülü nesne oluşturma için bir yoldur. Bir fabrika yöntemiyle olmadan, sadece sınıfının çağırır yapıcı doğrudan: Foo x = new Foo()
. Bu desen ile, yerine fabrika yöntemini çağırır: Foo x = Foo.create()
. Yapıcılar özel olarak işaretlenir, bu nedenle sınıfın dışında çağrılamazlar ve fabrika yöntemi, static
önce bir nesneye sahip olmadan çağrılabilecek şekilde işaretlenir .
Bu modelin birkaç avantajı vardır. Birincisi, fabrika birçok alt sınıftan (veya bir arayüzün uygulayıcılarından) seçim yapabilir ve bunu iade edebilir. Bu şekilde arayan, potansiyel olarak karmaşık bir sınıf hiyerarşisini bilmek veya anlamak zorunda kalmadan parametreler aracılığıyla istenen davranışı belirleyebilir.
Bir diğer avantaj, Matthew ve James'in belirttiği gibi, bağlantılar gibi sınırlı bir kaynağa erişimi kontrol etmektir. Bu , yeniden kullanılabilir nesnelerin havuzlarını uygulamanın bir yolu - bir nesneyi inşa etmek, kullanmak ve yıkmak yerine, inşaat ve yıkım pahalı süreçlerse, bunları bir kez inşa etmek ve geri dönüştürmek daha mantıklı olabilir. Fabrika yöntemi, varsa, kullanılmayan, somutlaştırılmış bir nesneyi döndürebilir veya nesne sayısı daha düşük bir eşiğin altındaysa bir tane oluşturabilir veya null
üst eşiğin üstünde ise bir istisna veya dönüş atabilir .
Wikipedia'daki makaleye göre, çoklu fabrika yöntemleri de benzer argüman türlerinin farklı yorumlarına izin verir. Normalde kurucu sınıfla aynı ada sahiptir, yani belirli bir imzası olan yalnızca bir kurucuya sahip olabilirsiniz . Fabrikalar çok kısıtlı değildir, yani aynı argüman türlerini kabul eden iki farklı yönteminiz olabilir:
Coordinate c = Coordinate.createFromCartesian(double x, double y)
ve
Coordinate c = Coordinate.createFromPolar(double distance, double angle)
Bu, Rasmus'un belirttiği gibi, okunabilirliği artırmak için de kullanılabilir.
NOT! " Statik fabrika yöntemi , Fabrika Yöntemi ile aynı DEĞİLDİR " (c) Etkili Java, Joshua Bloch.
Fabrika Yöntemi: "Nesne oluşturmak için bir arabirim tanımlayın, ancak arabirimi uygulayan sınıfların hangi sınıfın örnekleneceğine karar vermesine izin verin. Fabrika yöntemi, bir sınıfın alt sınıflara örnek oluşturmayı ertelemesine izin verir" (c) GoF.
"Statik fabrika yöntemi, bir sınıf örneğini döndüren statik bir yöntemdir." (c) Etkili Java, Joshua Bloch. Genellikle bu yöntem belirli bir sınıfın içindedir.
Fark:
Statik fabrika yönteminin ana fikri, nesne oluşturma üzerinde kontrol kazanmak ve bunu yapıcıdan statik yönteme devretmektir. Oluşturulacak nesnenin kararı, Soyut Fabrika'da yöntemin dışında yapılanlara benzer (ortak durumda, ancak her zaman değil). Fabrika Metodu'nun ana fikri (!), Fabrika Metodu içinde hangi sınıf örneğinin yaratılacağına dair karar vermektir. Örneğin klasik Singleton uygulaması, statik fabrika yönteminin özel bir durumudur. Yaygın olarak kullanılan statik fabrika yöntemlerine örnek:
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();
private Foo(boolean withBar){/*..*/}
public static Foo createWithBar(){return new Foo(true);}
public static Foo createWithoutBar(){return new Foo(false);}
- kodları açıklığa kavuşturabilen kurucuların aksine adlara sahiptir.
- her çağrı üzerine yeni bir nesne oluşturmanıza gerek yoktur - gerekirse nesneler önbelleğe alınabilir ve yeniden kullanılabilir.
- dönüş türünün bir alt türünü döndürebilir - özellikle, uygulama sınıfı arayan tarafından bilinmeyen bir nesneyi döndürebilir. Bu, statik fabrika yöntemlerinin dönüş türü olarak arabirimleri kullanan birçok çerçevede çok değerli ve yaygın olarak kullanılan bir özelliktir.
Her şey sürdürülebilirliğe kaynar. Bunu koymanın en iyi yolu, new
bir nesne oluşturmak için anahtar kelimeyi her kullandığınızda, yazdığınız kodu bir uygulamaya bağlarsınız.
Fabrika kalıbı, bir nesneyi oluşturma şeklinizi nesneyle yaptığınız işlemden ayırmanızı sağlar. Tüm nesnelerinizi yapıcıları kullanarak oluşturduğunuzda, nesneyi o uygulamaya kullanan kodu kablolamaya çalışırsınız. Nesnenizi kullanan kod, o nesneye "bağımlıdır". Bu yüzeyde 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ıflamayı düşünün) geri dönüp her şeyi yeniden sarmanız gerekir.
Günümüzde fabrikalar, Bağımlılık Enjeksiyonu kullanmak için büyük ölçüde kenara çekildi, çünkü kendini korumak biraz zor olan çok sayıda kazan plakası koduna ihtiyaç duyuyorlar. Bağımlılık Enjeksiyonu temel olarak fabrikalara eşdeğerdir, ancak nesnelerinizin bildirim yoluyla (yapılandırma veya ek açıklamalar yoluyla) nasıl birbirine bağlanacağını belirtmenize olanak tanır.
Bir sınıfın yapıcısı özelse, 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 onun dışında bir nesne oluşturamayız. Böylece sınıfın dışından x, y'ye erişemezsiniz. O zaman bu sınıfın kullanımı nedir?
İşte Cevap: FABRİKA yöntemi.
Yukarıdaki sınıfa aşağıdaki yöntemi ekleyin
public static Test getObject(){
return new Test();
}
Artık bu sınıf için onun dışından bir nesne oluşturabilirsiniz. Bu şekilde ...
Test t = Test.getObject();
Bu nedenle, sınıfın nesnesini özel yapıcısını çalıştırarak döndüren statik bir yönteme FACTORY yöntemi denir
.
Static Factory Method
, kamu kurucusuna göre herhangi bir yararımız var mı?
Bildiklerime bu yazıya biraz ışık katacağımı düşündüm. Bu tekniği yoğun olarak kullandık recent android project
. Bunun yerine bir sınıfı başlatmak için creating objects using new operator
de kullanabilirsiniz static method
. 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 kurucuyu her çağırışınızda bir nesne oluşturulur ancak bunu istemeyebilirsiniz. koşulun yerine getirilmediği sürece, yalnızca yeni bir nesne oluşturmak istediğinizde bir koşulu kontrol etmek istediğinizi varsayalım.Her seferinde Vinoth'un yeni bir örneğini oluşturmayacaksınız.
Etkili Java'dan alınan başka bir örnek .
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
Bu yöntem, bir boole ilkel değerini bir Boolean nesne referansına çevirir. Boolean.valueOf(boolean)
Yöntem bir nesne oluşturur asla bizi göstermektedir. static factory methods
Aynı nesneyi tekrarlanandan döndürme yeteneği, invocations
sınıfların herhangi bir zamanda hangi örneklerin var olduğu üzerinde sıkı kontrol sahibi olmalarını sağlar.
Static factory methods
aksine constructors
, dönüş türlerinden object
herhangi subtype
birini döndürebilirler. Bu esnekliğin bir uygulaması, bir API'nin sınıflarını herkese açık hale getirmeden nesneleri döndürebilmesidir. Uygulama sınıflarını bu şekilde gizlemek çok kompakt bir API'ya yol açar.
Calendar.getInstance () O yerel a bağlı oluşturur, yukarıda için harika bir örnek BuddhistCalendar
, JapaneseImperialCalendar
ya da varsayılan teker Georgian
.
Düşünebileceğim bir başka örnek Singleton pattern
, kurucularınızı özel getInstance
yaptığınız, her zaman sadece bir örnek bulunduğundan emin olduğunuz kendi yöntemini oluşturduğunuz yerdir.
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;
}
}
Fabrika yöntemi, bir nesnenin somutlaştırılmasını soyutlayan bir yöntemdir. Genel olarak fabrikalar, bazı arabirimi uygulayan yeni bir sınıf örneğine ihtiyacınız olduğunu bildiğinizde, ancak uygulayıcı sınıfı bilmediğinizde yararlıdır.
Bu, ilgili sınıfların hiyerarşileri ile çalışırken faydalıdır, bunun iyi bir örneği bir GUI araç takımıdır. Her widget'ın somut uygulamaları için yapıcıları zor kodlayabilirsiniz, ancak bir araç setini başka bir araçla değiştirmek isterseniz, değiştirmek için çok fazla yeriniz olurdu. Bir fabrika kullanarak, değiştirmeniz gereken kod miktarını azaltırsınız.
Statik fabrikadan kaynaklanan avantajlardan biri, API'nin nesneleri sınıflarını halka açmadan döndürebilmesidir. Bu, çok kompakt bir API'ya yol açar. Java'da bu, koleksiyon API'sını çok kompakt hale getiren yaklaşık 32 sınıfı gizleyen Collections sınıfı tarafından gerçekleştirilir.
Statik bir fabrika yöntemi, kullanılacak somut sınıfı yalnızca bir örneğin döndürmesini sağlamak istediğinizde iyidir.
Örneğin, bir veritabanı bağlantı sınıfında, veritabanı bağlantısını oluşturmak için yalnızca bir sınıfın olmasını isteyebilirsiniz, böylece Mysql'den Oracle'a geçmeye karar verirseniz, yalnızca bir sınıftaki mantığı değiştirebilirsiniz ve uygulamanın geri kalanı yeni bağlantıyı kullanın.
Veritabanı havuzu oluşturmak istiyorsanız, bu uygulamanın geri kalanını etkilemeden de yapılabilir.
Uygulamanın geri kalanını, fabrikada yapabileceğiniz değişikliklerden korur.
Statik olmasının nedeni, bazı sınırlı kaynakların (soket bağlantılarının veya dosya tanıtıcılarının sayısı) takip edilmesini istiyorsanız, bu sınıfın kaç tanesinin geçirildiğini ve geri döndüğünü izleyebilir, böylece sınırlı kaynak.
Özel yapıcı ile statik fabrika yöntemlerinin avantajlarından biri (örneklerin harici olarak oluşturulmadığından emin olmak için harici sınıflar için nesne oluşturma kısıtlanmış olmalıdır), örnek kontrollü sınıflar oluşturabilmenizdir . Örnek kontrollü sınıflar , programınız sırasında iki eşit farklı örneğin ( a.equals (b) olmadığını ve eğer programınız sırasında a == b varsa ) , eşittir yöntemi yerine == operatörü ile nesnelerin eşitliğini kontrol edebileceğiniz anlamına gelir. , Etkili Java'ya göre.
Statik fabrika yöntemlerinin aynı nesneyi tekrarlanan çağrılardan döndürme yeteneği, sınıfların herhangi bir zamanda hangi örneklerin var olduğu üzerinde sıkı kontrol sahibi olmalarını sağlar. Bunu yapan sınıfların örnek kontrollü olduğu söylenir. Örnek kontrollü sınıflar yazmanın birkaç nedeni vardır. Örnek denetimi, bir sınıfın tekil (Öğe 3) veya örneklenemez (Öğe 4) olduğunu garanti etmesini sağlar. Ayrıca, değişmez bir sınıfın (Madde 15) iki eşit örneğin bulunmadığının garantisini vermesine izin verir: a.equals (b) yalnızca ve == b ise. Bir sınıf bu garantiyi verirse, istemcileri eşittir (Object) yöntemi yerine == operatörünü kullanabilir ve bu da performansın artmasına neden olabilir. Enum tipleri (Madde 30) bu garantiyi sağlar.
Etkili Java, Joshua Bloch (Madde 1, sayfa 6)
statik
Bir üye 'statik' anahtar kelimesi ile beyan etti.
fabrika yöntemleri
Yeni nesneler oluşturan ve döndüren yöntemler.
Java'da
Programlama dili 'statik' anlamıyla ilgilidir, ancak 'fabrika' tanımıyla ilgili değildir.
Java uygulaması, java.util.Arrays ve java.util.Collections yardımcı sınıflarını içerir. Her ikisi de statik fabrika yöntemleri , örnekleri ve nasıl kullanılacağını içerir:
Arrays.asList("1","2","3")
Collections.synchronizedList(..), Collections.emptyList(), Collections.unmodifiableList(...)
(Sadece bazı örnekler, javadokları daha fazla yöntem örneği olup olmadığını kontrol edebilir https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html )
Ayrıca java.lang.String sınıfı bu tür statik fabrika yöntemlerine sahiptir :
String.format(...), String.valueOf(..), String.copyValueOf(...)