Bu yazımda design pattern’lara giriş yapmak istiyorum. Yazılımcılar her zaman amele işler yapmaktan kaçınır ve bu doğrultuda kendi tecrübelerini yansıtacakları pattern’lar oluştururlar. Aslında büyük çaplı projelerde her zaman karşılaştığımız sorunlardan biri olan benzer class üretme ve her benzer class için obje türetme sorununu çözen bir tasarım kalıbı olan Factory Pattern’i anlatacağım. Uzatmadan giriş yapalım.
Top üreten bir fabrika düşünelim. Futbol, voleybol ve basketbol topu. Fabrika bu 3 çeşit için birbirine benzer süreçler işler ve aslında her biri için farklı makineler kullanmazlar. Sadece ufak dokunuşlarla topların özelliklerini değiştirirler. Bu sayede her tip için makine alınması ihtiyacı çıkmaz, maliyet düşer ve zamandan kazanç sağlanır. Factory pattern de bizzat fabrika çalışma mantığına göre çalışır. Birbirine benzer class’ları ayrı ayrı workflow’larımızda türeteceğimize bir tane base class oluştururuz içerisinde yapacağımız ürünleri oluştururuz mantığıyla çalışmaktadır. Her seferinde tekrar nesne üretme maliyetinden, benzer classlar için ayrı tanımlamalar yapma ameleliğinden de bu sayede kurtuluruz. Çalışma mantığını kodla açıklayacağım daha anlaşılır olacağına inanıyorum.
Üretim yapacak araç tiplerimizi tanımlayalım. Bu enumlar sayesinde workflow’umuzda erişim sağlayabileceğiz.
1 2 3 4 5 6 | public enum VehicleType { Car = 1, Truck = 2, Motorcycle = 3 } |
Araçların ortak özelliklerini tanımlayalım. Pattern’in yapımıza, projemize uygun olduğunu bu interfacedeki metodlarımızın fazlalığından anlayabiliriz. Ne kadar az özellik varsa o kadar pattern’e uzak diyebiliriz.
1 2 3 4 | public interface IVehicle { void DisplayInfo(); } |
Ürünlerimizin classlarını oluşturalım. IVehicle interface’imizden türetilen araç tiplerini tanımlamamız gerekiyor. DisplayInfo metodumuzu interface gereği kullanmamız gerekiyor. Burada bir sınıf daha türetip DisplayInfo metodumuzu base’den de türetebiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Car : IVehicle { public void DisplayInfo() { Console.WriteLine("Araba"); } } public class Truck : IVehicle { public void DisplayInfo() { Console.WriteLine("Truck produced"); } } public class Motorcycle : IVehicle { public void DisplayInfo() { Console.WriteLine("Motorsiklet"); } } |
Fabrikanın temelini oluşturalım. Workflow Akışında ProduceVehicle sayesinde new ile yeni nesne türetme derdinden kurtuluyoruz.
1 2 3 4 | public interface IVehicleFactory { IVehicle ProduceVehicle(VehicleType type); } |
Fabrikamızı oluşturalım. Switch case yapısı ile anlaşılır olması için gösterdim. Factory içerisinde static class tanımlayıp classları üretip de yapabilirdik. Proje durumumuza göre şekillendirebiliriz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class VehicleFactory : IVehicleFactory { public IVehicle ProduceVehicle(VehicleType type) { IVehicle vehicle = null; switch (type) { case VehicleType.Car: vehicle = new Car(); break; case VehicleType.Truck: vehicle = new Truck(); break; case VehicleType.Motorcycle: vehicle = new Motorcycle(); break; } return vehicle; } } |
Yukarıda yazılan kodla anlayacağımız gibi araçları gruplayıp daha sonra fabrika yardımıyla workflow içerisinde kullanılabilir bir yapı ortaya çıkardık.