Fabrika Kalıbı
Coddy'nin C Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 55 / 61.
Factory deseni, nesne oluşturmayı tek bir fonksiyonda merkezileştirir. Programınızın her yerine malloc ve başlatma kodu dağıtmak yerine, ne oluşturulacağına karar veren ve kullanıma hazır bir nesne döndüren tek bir fonksiyonu çağırırsınız.
Bu desen, polimorfizm ile birleştirildiğinde özellikle güçlüdür. Bir fabrika, ortak bir temel işaretçi aracılığıyla farklı somut türler döndürebilir ve oluşturma ayrıntılarını çağırandan gizleyebilir. Çağıran sadece "bir şekil" ister ve fabrika bir daire mi, dikdörtgen mi yoksa başka bir şey mi inşa edeceğine karar verir.
İşte tipik bir factory uygulaması:
typedef enum {
SHAPE_CIRCLE,
SHAPE_RECTANGLE
} ShapeType;
Shape* create_shape(ShapeType type) {
switch (type) {
case SHAPE_CIRCLE:
return (Shape*)create_circle(5.0);
case SHAPE_RECTANGLE:
return (Shape*)create_rectangle(4.0, 3.0);
default:
return NULL;
}
}Fabrika bir tanımlayıcı (genellikle bir enum) alır ve hangi kurucunun çağrılacağını belirlemek için bir switch ifadesi kullanır. Oluşturulan gerçek türden bağımsız olarak bir Shape* döndürür. Çağıranın Circle veya Rectangle hakkında bilgi sahibi olmasına gerek yoktur — sadece temel tür ile çalışır:
Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s); // polimorfik çağrı
free_shape(s);Bu desen yeni türler eklemeyi kolaylaştırır: sadece yeni bir enum değeri ve factory içinde yeni bir case ekleyin. Kodunuzun geri kalanı değişmeden kalır.
Görev
KolayHadi bir Pet Factory (Evcil Hayvan Fabrikası) inşa edelim — tek bir fabrika fonksiyonu aracılığıyla farklı türde evcil hayvanlar oluşturan bir sistem. Oluşturma mantığını kodunuzun her yerine dağıtmak yerine, bir girdi tanımlayıcısına göre ne tür bir evcil hayvan oluşturulacağına karar veren tek bir yerde merkezileştireceksiniz.
Kodunuzu üç dosya halinde düzenleyeceksiniz:
pet.h:PET_DOG,PET_CATvePET_BIRDdeğerlerine sahip birPetTypeenum'ı tanımlayın.speak(birconst Pet*alan ve hiçbir şey döndürmeyen) için bir fonksiyon göstericisi içeren temel birPetstruct'ı oluşturun. BirPetTypealan ve birPet*döndürencreate_petfabrika fonksiyonunu ve temizlik için birfree_petfonksiyonunu deklare edin.pet.c: Her biri ilk üyesi olarakPetiçeren üç somut evcil hayvan struct'ı —Dog,CatveBird— tanımlayın. Her tür için bir speak fonksiyonu uygulayın:- Köpekler şunu yazdırır:
Woof! - Kediler şunu yazdırır:
Meow! - Kuşlar şunu yazdırır:
Tweet!
create_petfabrikasını uygulayın — doğru yapıcıyı çağırmak ve sonucu birPet*olarak döndürmek içinPetTypeüzerinde bir switch ifadesi kullanın. Geçersiz türler içinNULLdöndürün. Ayrılan belleği serbest bırakmak içinfree_petfonksiyonunu uygulayın.- Köpekler şunu yazdırır:
main.c: Evcil hayvan türünü temsil eden bir tam sayı okuyun (köpek için 0, kedi için 1, kuş için 2). Uygun evcil hayvanı oluşturmak için fabrikanızı kullanın, temelPet*göstericisi aracılığıylaspeakfonksiyonunu polimorfik olarak çağırın ve ardından evcil hayvanı serbest bırakın.
Programınız bir girdi alacaktır: hangi evcil hayvanın oluşturulacağını belirten bir tam sayı.
Girdi 0 olduğunda örnek çıktı:
Woof!Girdi 1 olduğunda örnek çıktı:
Meow!Girdi 2 olduğunda örnek çıktı:
Tweet!Factory deseninin güzelliği, main.c dosyasının Dog, Cat veya Bird struct'ları hakkında bilgi sahibi olmasına gerek duymamasıdır — sadece temel Pet türüyle çalışır. Daha sonra yeni bir evcil hayvan türü eklemek, evcil hayvanları kullanan hiçbir kodu değiştirmeden yeni bir enum değeri ve fabrikada yeni bir case eklemek anlamına gelir.
Kopya kağıdı
Factory deseni, nesne oluşturmayı tek bir fonksiyonda merkezileştirerek oluşturma ayrıntılarını çağırandan gizler.
Bir factory fonksiyonu, bir tanımlayıcı (genellikle bir enum) alır ve hangi kurucunun çağrılacağını belirlemek için bir switch ifadesi kullanarak bir temel tür işaretçisi döndürür:
typedef enum {
SHAPE_CIRCLE,
SHAPE_RECTANGLE
} ShapeType;
Shape* create_shape(ShapeType type) {
switch (type) {
case SHAPE_CIRCLE:
return (Shape*)create_circle(5.0);
case SHAPE_RECTANGLE:
return (Shape*)create_rectangle(4.0, 3.0);
default:
return NULL;
}
}Çağıran taraf yalnızca temel türle çalışır, bu da polimorfik davranışı mümkün kılar:
Shape* s = create_shape(SHAPE_CIRCLE);
s->draw(s); // polimorfik çağrı
free_shape(s);Avantajları: Yeni türler eklemek, factory'yi kullanan mevcut kodu değiştirmeden yalnızca yeni bir enum değeri ve switch durumu eklemeyi gerektirir.
Kendin dene
#include <stdio.h>
#include "pet.h"
int main(void) {
int type;
scanf("%d", &type);
// TODO: Uygun evcil hayvanı oluşturmak için fabrikayı kullanın
// Hint: int değerini PetType türüne dönüştürün
// TODO: speak fonksiyonunu Pet* işaretçisi üzerinden polimorfik olarak çağırın
// TODO: Evcil hayvanı serbest bırakın
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1Modüler Programlama Temelleri
Başlık DosyalarıInclude Guard'larKaynak DosyalarıStatik FonksiyonlarÖzet: Modüler Hesap Makinesi4Kapsülleme
Opaque Pointer KavramıOpaque Struct TanımlamaGetter ve Setter MetotlarıSetter Metotlarında DoğrulamaÖzet: Gizli Kutu2Nesneler ve Metotlar
Nesne Olarak Struct'lar'Self' İşaretçisiConst Doğruluğuİşaretçi vs DeğerYardımcı MetotlarÖzet: Point Manager5Proje: Basit Banka Hesabı
Proje KurulumuHesabın Oluşturulması3Nesne Yaşam Döngüsü
Constructor DeseniDestructor DeseniStack İlklendirmeDerin KopyalamaÖzet: String Wrapper6Kompozisyon Yoluyla Kalıtım
Struct Gömmeİlk Üye KuralıÜst Üyelere ErişimUpcastingÖzet: Şekil Hiyerarşisi