Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 8 của 8
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    DesignPattern | Abstract Factory trong lập trình C#

    Mô hình của nhc1987 có tên là composite thể hiện mối quan hệ cha - con.

    Cậu áp dụng cũng được.

    Mình nhớ tối hồi học OOP. Ông thầy có đưa ra bài toán tính tiền của 1 cái máy biết máy đó bao gồm các chi tiết đơn và chi tiết phức. Trong chi tiết phức lại có chi tiết đơn. Ỗng cài đặt cái mô hình này mà mình khâm phục miết đến giờ làm sao có thể tốt đến như vậy.

    Miết sau này mới biết nó là 1 mô hình chuẩn trong Pattern Object.
    ---------------------------------------
    Góp vui 1 chút nha:



    Đây là mô hình cơ bản và quan trọng trong Design Patterns tên là Abstract Factory.

    Mã:
     // "AbstractFactory"  abstract class AbstractFactory  {    public abstract AbstractProductA CreateProductA();    public abstract AbstractProductB CreateProductB();  }  // "ConcreteFactory1"   class ConcreteFactory1 : AbstractFactory  {    public override AbstractProductA CreateProductA()    {      return new ProductA1();    }    public override AbstractProductB CreateProductB()    {      return new ProductB1();    }  }   // "ConcreteFactory2"   class ConcreteFactory2 : AbstractFactory  {    public override AbstractProductA CreateProductA()    {      return new ProductA2();    }    public override AbstractProductB CreateProductB()    {      return new ProductB2();    }  }
    Mã:
      // "AbstractProductA"   abstract class AbstractProductA  {  }    // "AbstractProductB"   abstract class AbstractProductB  {    public abstract void Interact(AbstractProductA a);  }  // "ProductA1"   class ProductA1 : AbstractProductA  {  }   // "ProductB1"   class ProductB1 : AbstractProductB  {    public override void Interact(AbstractProductA a)    {      Console.WriteLine(this.GetType().Name +        " interacts with " + a.GetType().Name);    }  }   // "ProductA2"   class ProductA2 : AbstractProductA  {  }   // "ProductB2"   class ProductB2 : AbstractProductB  {    public override void Interact(AbstractProductA a)    {      Console.WriteLine(this.GetType().Name +        " interacts with " + a.GetType().Name);    }  }
    Mã:
    class Client  {    private AbstractProductA AbstractProductA;    private AbstractProductB AbstractProductB;     // Constructor    public Client(AbstractFactory factory)    {      AbstractProductB = factory.CreateProductB();      AbstractProductA = factory.CreateProductA();    }     public void Run()    {      AbstractProductB.Interact(AbstractProductA);    }  }
    Mã:
    class MainApp  {    public static void Main()    {      // Abstract factory #1      AbstractFactory factory1 = new ConcreteFactory1();      Client c1 = new Client(factory1);      c1.Run();       // Abstract factory #2      AbstractFactory factory2 = new ConcreteFactory2();      Client c2 = new Client(factory2);      c2.Run();       // Wait for user input      Console.Read();    }  }
    Code thì copy lại đơn giản thôi. Nhưng mà hiểu được mô hình này thì các bạn sẽ nắm khoảng 70% nền tảng kiến thức của Design Patterns.

    Vậy nên mình đố các bạn có thể áp dụng nó vào chương trình của mình (chỉ cần nêu ý tưởng mà thôi).

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    We use the Abstract Factory design pattern when:
    - the system needs to be independent from the way the products it works with are created
    - the system is or should be configured to work with multiple families of products
    - a family of products is designed to work only all together
    - the creation of a library of products is needed, for which is relevant only the interface, not the implementation, too.

    The example at the beginning of the article can be extended to addresses, too. The AbstractFactory class will contain methods for creating a new entry in the information manager for a phone number and for an address, methods that produce the abstract products Address and PhoneNumber, which belong to AbstractProduct classes. The AbstractProduct classes will define methods that these products support: for the address get and set methods for the street, city, region and postal code members and for the phone number get and set methods for the number.
    The ConcreteFactory and ConcreteProduct classes will implement the interfaces defined above and will appear in our example in the form of the USAddressFactory class and the USAddress and USPhoneNumber classes. For each new country that needs to be added to the application, a new set of concrete-type classes will be added. This way we can have the EnglandAddressFactory and the EnglandAddress and EnglandPhoneNumber that are files for English address information.

    Another example, this time more simple and easier to understand, is the one of a pizza factory, which defines method names and returns types to make different kinds of pizza.
    The abstract factory can be named AbstractPizzaFactory, RomeConcretePizzaFactory and MilanConcretePizzaFactory being two extensions of the abstract class.
    The abstract factory will define types of toppings for pizza, like pepperoni, sausage or anchovy, and the concrete factories will implement only a set of the toppings, which are specific for the area and even if one topping is implemented in both concrete factories, the resulting pizzas will be different subclasses, each for the area it was implemented in.


    [source] http://hocit.com/forum/showthread.php?t=7541

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bác viết cũng được, đọc mô hình thì hiểu, nhưng để đọc code hiểu được thì phải mất một thời gian chứ đọc qua thì không thể hiểu luôn được, phải có thời gian.

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Đây là mô hình Patterns đầu tiên mà hình học được, và mình rất thích nó vì nó giúp mình hiểu thêm nhiều điều về thiết kế chương trình HĐT hơn. Ngoài ra vẫn còn các mẫu Patterns hay nữa như Singletion, Adapter, Observer...

    Mô hình Abstract Factory hiểu như là "nhà máy trừu tượng" sản xuất ra các "sản phẩm trừu tượng".

    Ví dụ như công ty A sản xuất sp Giấy và yêu cầu bạn viết chương trình quản lý ví dụ như thống kê các loại giấy và tính tổng giá trị...

    Bạn sẽ thiết kế như thế nào?
    Nghĩ đơn giản là:
    - 1 class NhaMay (Gồm các thuộc tính như tên công ty, các phương thức như inDanhSach(), tinhTong(),...)
    - và 1 class Giay (gồm các thuộc tính như Gia, các đặc tính, phương thức inThongTin(),....)

    OK! Và bạn hoàn toàn có thể thành công với yêu cầu đầu tiên là chương trình quản lý công ty A sản xuất Giấy. Mình tin là làm được điều đó.

    --------------------

    Nhưng nếu sau nay công ty A mở rộng thị trường, họ sản xuất thêm sản phẩm mực. Và yêu cầu ta cập nhật chương trình. Ta sẽ làm gì ???? sẽ viết lại chương trình à... hay sửa lại nhưng rất khó khăn.

    Rõ ràng bạn bị sai khi không thấy được hướng phát triển sau này của 1 ứng dụng

    Abstract Factory giải quyết vấn đề này bằng 1 lớp trừu tượng.
    Cả GiấyMực đều có 1 điểm chung là Sản Phẩm. Và vì vậy chúng sẽ được kế thừa từ sản phẩm.

    Và lúc này bản thiết kết sẽ như sau:

    Mã:
    // Const xác định loại sản phẩmpublic enum LoaiSanPham{    Giay,    Muc} // Lớp trừu tượng SanPhampublic abstract class SanPham{    string m_sTenSP;    int m_nGia;    protected LoaiSanPham m_loaiSP;     // Property _TenSP    public string _TenSP    {        get { return m_sTenSP; }        set { m_sTenSP = value; }    }     // Property _LoaiSP    public LoaiSanPham _LoaiSP    {        get { return m_nLoaiSP; }    }     // Property _Gia    public int _Gia    {        get { return m_nGia; }        set { m_nGia = value; }    }     // Hàm ảo giống In_Thong_Tin    public abstract void In_Thong_Tin();}

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Và bạn sẽ có lớp SanPhamGiay, SanPhamMuc


    Mã:
    class SanPhamGiay : SanPham{    string m_sDactinhSP;     public string _DactinhSP    {        get { return m_sDactinhSP; }        set { m_sDactinhSP = value; }    }     public override void In_Thong_Tin()    {        Console.Write("Giay: {0} Loai: {1} Gia: {2} 
    ",             _TenSP,             _DacTinhSP,            _Gia);    }     public SanPhamGiay()    {        m_loaiSP= LoaiSanPham.Giay;    }} class SanPhamMuc : SanPham{    string m_sLoaiMuc;      string m_sMauMuc;     public string _LoaiMuc    {        get { return m_sLoaiMuc; }        set { m_sLoaiMuc = value; }    }     public string _MauMuc    {        get { return m_sMauMuc; }        set { m_sMauMuc = value; }    }     public override void In_Thong_Tin()    {        Console.Write("Muc: {0} Loai Muc: {1}  Mau Muc: {2}  Gia: {3} 
    ",            _TenSP,            _LoaiMuc,            _MauMuc,            _Gia);    }     public SanPhamMuc()    {        m_loaiSP = LoaiSanPham.Muc;    }}

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Một câu hỏi là tại sao phải phức tạp như vậy...

    Một chương trình Hướng Đối Tượng nó có thể dài rất nhiều, nhưng cái hay là các function được tách nhỏ, và chắc chắn 1 hàm ko được dài quá 1 trang màn hình.

    Điều này sẽ giúp cho bạn dễ quản lý CODE sau này.

    Hơn nữa kế thừa giúp cho chương trình mở rộng.
    Giả sử Cty A có sản xuất thêm Sách, hay Cặp, ba lô... nữa cũng là chuyện nhỏ. Bạn chỉ cần kết thừa và tiếp tục.

    Với đặc điểm ĐA HÌNH của OOP thì như SanPham sẽ đại diện cho tất cả các lớp dẫn xuất kết thừa nó, vì thế class CongTy ko cần biết tới bất kỳ đối tượng SanPhamGiay, hoặc SanPhamMuc, hay các sản phẩm mà sau này nó sx nữa. Nó chỉ sử dụng lớp trừu tượng SanPham. Đó là ý nghĩa của ABSTRACT FACTORY, chúng ta sẽ ko bao giờ sửa code class CongTy dù sau này nó có mở rộng.


    Mã:
    class CongTy{    SanPham[] m_sanPham;    int m_SoSP;     public CongTy()    {        m_SoSP = 0;        m_sanPham = new SanPham[300];    }     public void San_Xuat(SanPham sp)    {        m_sanPham[m_SoSP] = sp;        m_SoSP++;    }     public void In_Danh_Sach(LoaiSanPham lsp)    {        for (int i = 0; i < m_SoSP; i++)                    if (m_sanPham[i]._LoaiSP == lsp)                m_sanPham[i].In_Thong_Tin();            }     public int Tinh_Tong(LoaiSanPham lsp)    {        int nTong= 0;         for (int i = 0; i < m_SoSP; i++)                    if (m_sanPham[i]._LoaiSP == lsp)                nTong += m_sanPham[i]._Gia;        return nTong;    }}

  7. #7
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Abstract (trừu tượng) đã thể hiện ở class CongTy.

    Và bây giờ à class Client. Nó sẽ thực thi và điều khiển CongTy hoạt động.

    Mã:
    class Client{        CongTy m_congTy;                public Client()        {            m_congTy = new CongTy();        }         static void Main()        {                SanPhamGiay giayA4 = new SanPhamGiay();                giayA4._Gia = 100;                giayA4._TenSP = "Giay A4";                giayA4._DacTinhSP = "Trang";                  SanPhamGiay giayA3 = new SanPhamGiay();                giayA4._Gia = 200;                giayA4._TenSP = "Giay A3";                giayA4._DacTinhSP = "Trang";                 SanPhamGiay giayA2 = new SanPhamGiay();                giayA4._Gia = 200;                giayA4._TenSP = "Giay A2";                giayA4._DacTinhSP = "Xam";                 m_congTy.San_Xuat(giayA4);                m_congTy.San_Xuat(giayA3);                m_congTy.San_Xuat(giayA2);                 ....        }}
    Hay có thể là

    Mã:
    // Sản xuất mực SanPhamMuc mucIn = new SanPhamMuc();mucIn._Gia = 600;mucIn._TenSP = "Muc #1";mucIn._MauMuc = "Xanh"; SanPhamMuc mucViet = new SanPhamMuc();mucViet._Gia = 700;mucViet._TenSP = "Muc #2";mucViet._MauMuc = "Xanh"; m_congTy.San_Xuat(mucIn);m_congTy.San_Xuat(mucViet);  // In danh sáchm_congTy.In_Danh_Sach(LoaiSanPham.Giay);m_congTy.In_Danh_Sach(LoaiSanPham.Muc);
    Ở đây mình chỉ trừu tượng Sản phẩm.
    Abstract Factory còn trừu tượng cả Nhà máy nữa bởi vì các công ty như sản xuất xe, sản xuất điện tử đơn giản đều là nhà máy. Và họ có thể sử dụng ở mọi điều kiện.

    Hy vọng sẽ giúp ích cho các bạn!
    Cám ơn

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Bài viết của bạn rất hay. Cám ơn bạn.

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •