Hướng dẫn sử dụng Factory trong Design Pattern

Bài viết được sự cho phép của tác giả Nguyễn Thảo

Xin chào các bạn, bài viết hôm nay mình sẻ giới thiệu đến các bạn Factory Design Pattern dùng thế nào trong lập trình C#, Winform.

[C#] How to using Factory Design Pattern

Factory Pattern  là một design pattern thuộc nhóm khởi tạo (Creational patterns).

Pattern này được sinh ra nhằm mục đích khởi tạo một đối tượng mới mà không cần thiết phải chỉ ra một cách chính xác class nào sẽ được khởi tạo.

  30 tiện ích Chrome cho designer và dev
  9 công cụ siêu tiện lợi cho cả Developer và Designer

Factory Method Pattern giải quyết vấn đề này bằng cách định nghĩa một factory method cho việc tạo đối tượng, và các lớp con thừa kế có thể override phương thức này để chỉ rõ đối tượng nào sẽ được khởi tạo.

Hướng dẫn sử dụng Factory trong Design Pattern

Bây giờ, mình sẽ có một ví dụ, cho các bạn dễ hiểu về factory design pattern này.

Mình có yêu cầu viết một ứng dụng, nạp tiền điện thoại cho các mạng điện thoại Việt Nam: Mobifone, VinaPhone, Viettel, Vietnamobile, Gmobile.

Request yêu cầu gởi đến ứng dụng của chúng ta gồm 2 tham số: số thoại cần nạp tiền và số tiền.

Thường trong bài viết này, chúng ta sẽ sử dụng một thiết bị modern GMS và sử dụng tập lệnh AT-Command xài lệnh USSD để nạp tiền vào tài khoản cho người dùng.

Nhưng có rắc rối ở đây là mỗi nhà mạng, đều có cấu trúc kiểm tra số dư tài khoản, hay cú pháp nạp tiền đều khác nhau.

Vậy làm sao khi gởi đến chúng ta sẽ điều hướng cho từng class nhà mạng.

Sơ đồ Design Pattern:

Hướng dẫn sử dụng Factory trong Design Pattern

Đầu tiên, mình sẽ tạo một InterFace INetwork.cs C#:

namespace FactoryPatternDemo
{
    public interface INetwork
    {
        string GetNameNetWork();
        string CheckAccountMoney();
        string GetCarrierNumber();

    }
}
C#

Trong này mình khai báo ba phương thức sẵn: lấy tên nhà mạng, kiểm tra số dư tài khoản, và lấy đầu số của mỗi nhà mạng.

Tiếp đến mình sẽ tạo 5 class cho mỗi nhà mạng: viettel.cs, mobifone.cs, vinaphone.cs, vietnamobile.cs, gmobile.cs

Mỗi class này mình đều implement đến interface INetwork

  1. Viettel.cs
class Viettel : INetwork
{
    public string CheckAccountMoney()
    {
        return "*101#";
    }

    public string GetCarrierNumber()
    {
        return "086, 096, 097, 098, 032, 033, 034, 035, 036, 037, 038, 039";
    }

    public string GetNameNetWork()
    {
        return "VIETTEL";
    }
    
}
C#

2. Mobifone.cs

class Mobifone : INetwork
{
    public string CheckAccountMoney()
    {
        return "*101#";
    }

    public string GetCarrierNumber()
    {
        return "090, 093, 0120, 0121, 0122, 0126, 0128, 089";
    }

    public string GetNameNetWork()
    {
        return "MOBIFONE";
    }
}
C#

3. Vinaphone.cs

public class Vinaphone : INetwork
{
    public string CheckAccountMoney()
    {
        return "*101#";
    }

    public string GetCarrierNumber()
    {
        return "091, 094, 083, 084, 085, 081, 082";
    }

        public string GetNameNetWork()
    {
        return "VINAPHONE";
    }
}
C#

4. Vietnamobile.cs

public class Vietnamobile : INetwork
{
    public string CheckAccountMoney()
    {
        return "*101#";
    }

    public string GetCarrierNumber()
    {
        return "092, 056, 058";
    }

    public string GetNameNetWork()
    {
        return "VIETNAMOBILE";
    }
}
C#

5. Gmobile.cs

public class Gmobile : INetwork
{
    public string CheckAccountMoney()
    {
        return "*101#";
    }

    public string GetCarrierNumber()
    {
        return "099, 059";
    }

    public string GetNameNetWork()
    {
        return "GMOBILE";
    }
}
C#

Tiếp đến mình sẽ tạo một Enum NetworkType.cs

public enum NetworkType
{
    VIETTEL,
    MOBIFONE,
    VINAPHONE,
    VIETNAMOBILE,
    GMOBILE,
}
C#

Tạo một class abstract NetworkFactory.cs:

public abstract class NetworkFactory
{
    public abstract INetwork Create(NetworkType type);
}
C#

Tiếp đến là một class ConcreteCreator.cs để điều hướng cho từng nhà mạng:

class ConcreteCreator : NetworkFactory
{
    public override INetwork Create(NetworkType type)
    {
        switch (type)
        {
            case NetworkType.VIETTEL:
                return new Viettel();
               
            case NetworkType.MOBIFONE:
                return new Mobifone();

            case NetworkType.VINAPHONE:
                return new Vinaphone();

            case NetworkType.VIETNAMOBILE:
                return new Vietnamobile();

            case NetworkType.GMOBILE:
                return new Gmobile();
            default: 
                throw new ArgumentException("Invalid type", "type");

        }
    }
}
C#

Và bây giờ chúng ta sẽ sử dụng hàm trong form program.cs

namespace FactoryPatternDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var factory = new ConcreteCreator();
            INetwork viettel = factory.Create(NetworkType.VIETTEL);
            Console.WriteLine(viettel.GetNameNetWork());
            Console.WriteLine(viettel.GetCarrierNumber());
            Console.WriteLine("===========================================");

            INetwork vinaphone = factory.Create(NetworkType.VINAPHONE);
            Console.WriteLine(vinaphone.GetNameNetWork());
            Console.WriteLine(vinaphone.GetCarrierNumber());
            Console.WriteLine("===========================================");

            INetwork mobiphone = factory.Create(NetworkType.MOBIFONE);
            Console.WriteLine(mobiphone.GetNameNetWork());
            Console.WriteLine(mobiphone.GetCarrierNumber());
            Console.WriteLine("===========================================");

            INetwork vietnamobile = factory.Create(NetworkType.VIETNAMOBILE);
            Console.WriteLine(vietnamobile.GetNameNetWork());
            Console.WriteLine(vietnamobile.GetCarrierNumber());
            Console.WriteLine("===========================================");

            INetwork gmobile = factory.Create(NetworkType.GMOBILE);
            Console.WriteLine(gmobile.GetNameNetWork());
            Console.WriteLine(gmobile.GetCarrierNumber());

            Console.ReadLine();
        }
    }
}
C#

Và dưới đây là kết quả khi chúng ta chạy ứng dụng:

Hướng dẫn sử dụng Factory trong Design Pattern

Bây giờ, các bạn muốn viết hàm gì chung xử lý cho từng nhà mạng điện thoại, các bạn chỉ cần khai báo tên hàm vào Interface INetwork.cs.

Và sau đó các bạn vào từng class nhà mạng Override lại phương thức để thực hiện theo mong muốn của mình.

Hy vọng bài viết sẽ giúp ích được cho các bạn.

Thanks for watching!

Bài viết gốc được đăng tải tại laptrinhvb.net

Có thể bạn quan tâm:

Xem thêm các việc làm designer hấp dẫn tại TopDev