Design patterns
Singleton design pattern
Jan 18th
Singleton design pattern รูปแบบการออกแบบ class ในความต้องการที่ว่า เราอยาก ให้มีการสร้าง instance ของ class เพียง instance เดียวตลอดการทำงานของโปรแกรม ซึ่งผู้เรียกใช้สามารถเข้าถึงได้ผ่านทาง global access point หรือจุดที่เข้าถึง ที่เป็น global
สำหรับตัวอย่างการใช้งานของ pattern นี่นั้นเรามักจะใช้กับ ส่วนที่ต้องการให้มีเพียงหนึ่งเดียว เช่น file system หรือ windows manager เป็นต้น
โครงส้รางของ Singleton design pattern
จากโครงส้รางของ singleton design pattern เราจะเห็นว่า class ที่เป็น singleton นั้นเราจะให้มีการ ส้ราง instance ของตัวเอง ผ่านทาง Method ที่ชื่อว่า Instance() เพื่อให้เข้าใจง่ายขึ้นเราลองมาดูที่ code ตัวอย่างกันครับ
// Singleton class implements that simplest version of the Singleton
// design pattern.
//
public sealed class Singleton
{
private static readonly Singleton _instance = new Singleton();
// make the default constructor private, so that no can directly create it.
private Singleton()
{
}
// public property that can only get the single instance of this class.
public static Singleton Instance
{
get
{
return _instance;
}
}
}
<< ตัวอย่าง code จาก Design Pattern: Singleton in C# เขียนโดย Pedro Silva (darthpedro99@hotmail.com) >>
จาก code เราจะเห็นว่า class นั้นจะถูกกำหนด ให้เป็น seal class ก็คือจะไม่ได้มีการ inmplement class หรือ สืบทอด class นี้ ต่อไปเราจะพบว่า ตัวแปรที่ชื่อว่า instance นั้นเป็นตัวแปรที่ ชี้ไปยัง instance ของ class ครับ และมันถูกกำหนดให้เป็น stactic ทำให้มัน ถูกสร้างขึ้นมาครั้งเดียว หรือ instance เดียว เมื่อมีการ access ครั้งแรกเท่านั้น สำหรับการ access ครั้งต่อไป มันก็จะ ให้ instance เดิมครับ และมันถูกกำหนดให้เป็น readonly ไม่สามารถเปลี่ยนหรือแก้ไข ใด ๆ นะครับ
อีกอย่างที่สำคัญคือ หากต้องการที่จะได้ instance ของ class นี้นั้นจะต้อง access ผ่านทาง properties (หรือ method ) ที่ชื่อว่า Instance ซึ่งเป็นจุดเดียวที่ อนุญาติให้เข้าถึง instance ของ object นี้
ลองมาดูตัวอย่าง การใช้งานจริงกัน นะครับ
// singleton class
//----------------------------------------------
public sealed class LoadBalancer
{
private static readonly LoadBalancer _instance;
private List<string> _servers = new List<string>();
private Random _random = new Random();
// Lock synchronization object
private static object syncLock = new object();
// Constructor (protected)
protected LoadBalancer()
{
// List of available servers
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
// Support multithreaded applications through
// 'Double checked locking' pattern which (once
// the instance exists) avoids locking each
// time the method is invoked
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}
// Simple, but effective random load balancer
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
เป็น class สำหรับ ทำ random เพื่อจ่ายการทำงาน ให้กับ server โดย instance ของ class จะ access ได้ผ่านท่าง GetLoadBalancer() ครับ
ข้อสังเกตุ นะครับ สำหรับการใส่ lock(syncLock) ไว้ก่อนการสร้าง instance เป็นการ ทำเพื่อให้สามารถนำ code นี้ไปใช้ในกรณี ที่มีหลาย thread ครับ
ดูตัวอย่างของการใช้ class นี่นะครับ
class MainApp
{
// <summary>
// Entry point into console application.
// </summary>
static void Main()
{
LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
LoadBalancer b4 = LoadBalancer.GetLoadBalancer();
// Same instance?
if (b1 == b2 &amp;amp;amp;amp;&amp;amp;amp;amp; b2 == b3 &amp;amp;amp;amp;&amp;amp;amp;amp; b3 == b4)
{
Console.WriteLine("Same instance\n");
}
// Load balance 15 server requests
LoadBalancer balancer = LoadBalancer.GetLoadBalancer();
for (int i = 0; i < 15; i++)
{
string server = balancer.Server;
Console.WriteLine("Dispatch Request to: " + server);
}
// Wait for user
Console.ReadKey();
}
}
จะเห็น ว่าการเรียกใช้ เรานะทดสอบ การทำงานของ class ด้วยการส้ราง LoadBalance b1 , b2, b3, b4 เพื่อทดสอบว่า ทั้งหมดเป็น instance เดียวกัน
instance ของ class LoadBalancer จะถูกสร้าง ครั้งแรกครั้งเดียว เมื่อเรากำหนดค่าให้กับ b1
ในส่วนที่สองเป็นการ ทดสอบว่า มีการจ่ายงานให้กับ server หรือไม่อย่างไร
คงพอเข้าใจนะครับ เป็น การสร้างและทดสอบ การทำงาน singleton design pattern
คงพอที่ได้ แนวคิดในการใช้งาน นะครับ สำหรับ thread safe นั้นหากต้องการดูเพิ่มเติม ได้ที่ Design Pattern: Singleton in C#
ธีระพงษ์ สนธยามาลย์ Soft Speed Solution ’s senior programmer s_teearpong2000@yahoo.com
Factory Method Design Pattern
Jan 18th
Factory pattern เป็น design pattern ที่จะสร้าง instance ของ class ที่ต้องการ ตามข้อมูลที่กำหนดให้ไป หรือผู้ใช้เป็นผู้เลือกว่าจะ ส้ราง object ใด และ class เหล่านี้ที่ ถูกสร้างขึ้นนั้นมักจะ มี parent ร่วมกัน และก็มี method บางส่วนเหมือนกัน แต่ จะทำงานต่างกันออกไป
โครงสร้างของ Factory pattern

จากโครงสร้าง จะเห็นว่า เราจะมี abstract class ที่ชื่อว่า Product และมี child เป็น ProductB และ ProductA ซึ่งทั้งสอง class นี้ได้ทำการ implement Product แต่เราจะไม่สร้าง object ของทั้งสอง class นี้โดยตรงนะครับ
เราจะสร้าง object ของ สอง class นี้ผ่านทาง CreateProduction(int spec) method ของ ProductFactory class โดยที่ parameter spec นั้นเป็นตัวที่จะบอกกับ Createproduction(int spec) ว่าเราต้องการสร้าง object ของ ProductB หรือ ProductA นั่นเอง เป็นไงครับพอจะเข้าใจไหมครับ
ตัวอย่างของการนำไปใช้กันบ้าง
ตัวอย่างที่เห็นชัดเจน หากเราเคยใช้งาน หรือเคยทดลองใช้ Enterprise Library ของ Microsoft เราจะพบว่า ได้มีการประยุกต์ใช้ factory pattern เช่น ใน Data Access Application Block ของ Enterprise Library.
ใน Data Access Application block นั้นมี class ที่ชื่อว่า Database ( Product class ) ซึ่งเป็น base class ให้กับ SqlDatabase และ OracleDatabase classed ( ProductA, ProductB ) และ factory class ก็คือ CreateDataBase(string name) ( Createproduct(spec))
CreateDatabase method นั้นทำหน้าที่ สร้าง instance ของ Database ชนิดที่ต้องการ ซึ่ง อาจเป็น SqlDatabase หรือ OracleDatabase ขึ้นอยู่กับ ค่าที่ส่งผ่าน parameter ที่ชื่อ name
สิ่งที่เราจะสังเกตเห็นก็คือ ว่า CreateDatabase เป็น static method นะครับ
ตัวอย่างการใช้งาน
interface IPizza
{
double getPrice();
}
abstract class Pizza : IPizza
{
public abstract double getPrice();
}
class HamAndMushroomPizza : Pizza {
override
public double getPrice() {
return 8.5;
}
}
class DeluxePizza : Pizza {
override
public double getPrice() {
return 10.5;
}
}
class HawaiianPizza : Pizza {
override
public double getPrice() {
return 11.5;
}
}
class PizzaFactory {
public enum PizzaType {
HamMushroom,
Deluxe,
Hawaiian
}
public static IPizza createPizza(PizzaType pizzaType) {
switch (pizzaType) {
case PizzaType.HamMushroom:
return new HamAndMushroomPizza();
case PizzaType.Deluxe:
return new DeluxePizza();
case PizzaType.Hawaiian:
return new HawaiianPizza();
}
throw new ArgumentException("The pizza type " + pizzaType + " is not recognized.");
}
}
class PizzaLover {
public static void Main (string[] args) {
PizzaFactory.PizzaType[] pizzaTypes = { PizzaFactory.PizzaType.HamMushroom,
PizzaFactory.PizzaType.Deluxe,
PizzaFactory.PizzaType.Hawaiian};
foreach (PizzaFactory.PizzaType pizzaType in pizzaTypes) {
System.Console.WriteLine("Price of " + pizzaType + " is " +
PizzaFactory.createPizza(pizzaType).getPrice());
}
}
}
ครับคงพอได้ concept นะครับ
teerapong sontayaman senior programmer , Soft Speed Solution , s_teerapong2000@yahoo.com
รู้จักกับ Design Patterns
Jan 4th
โปรแกรมเมอร์ หรือ ผู้ที่อยู่ในวงการการพัฒนาโปรแกรม จะรู้จักกับคำว่า design pattern ไม่มากก็น้อย หลายคนก็รู้จักดี เพราะใช้งานอยู่ หลายคน ก็เรียนรู้มาในหลักสูตร แต่ก็ไม่เคยที่จะคิดใช้ หรือ ไม่ก็ไม่รู้ว่าจะใช้อย่างไรตอนไหน ซึ่งระหว่าเรียนก็ไม่เคยได้เห็น การนำไปใช้จริง หรือบางคนก็เคยแต่ได้ยิน ไม่รู้ว่าจะนำไปใช้อะไรอย่างไร อันนี้ผมก็เคยเป็นเหมือนกัน ครับ ว่าเอ มันคืออะไรกัน จนได้มีโอกาสไปเรียน หลักสูตรซอฟต์แวร์ เอนจิเนียริง จึงได้รู้จัก แต่ก็ยังคงไม่ชัดเจน ไม่รู้การนำไปประยุกค์ใช้อย่างไร
ครับ วันนี้เพื่อให้เป้นประโยชน์กับ ท่านที่สนใจ โปรแกรมเมอร์ทั้งหลาย ผมจะกล่าวถึง Design pattern ในเชิงการนำไปใช้ และปฏิบัติ ว่ามันเป็นอย่างไร นำไปใช้อย่างไร ซึ่งในบทความนี้จะกล่าวถึงความหมายของ Design pattern ทำไมเขาถึงพูดว่าเป็นรูปแบบ ของ knowledgs resues และ design pattern มันช่วยให้เราสร้าง software ที่ดีกว่าได้อย่างไร
สำหรับ Design pattern นั้นมีอยู่มากมาย หลากหลายการนำไปใช้ ซึ่งผมก็คงจะไม่พูดทั้งหมด ก็จะขอพูด เฉพาะ singleton factory model-view-controller และ command pattern ครับ และก็จะพูดถึงการ ใช้งานร่วมกัน เพื่อสร้าง software ให้มีสถาปัตยกรรมที่มี ความ ทนทานและ ยืดหยุ่น ตามหลักของ software engineering และจะแสดงให้เห็น ถึงการ แยก businesslogic จาก presentation layer โดยการใช้งาน model-view-controller และรวมถึงการใช้ command polymorphism โดยใช่้ command pattern ครับ…
สิ่งที่สำคัญ ครับคือการที่เราสามารถเขาใจการทำงานและการนำไปใช้ แล้ว จะเปลี่ยนวิถีการสร้าง software architecture ตลอดไป ครับ …