Chuyển đến nội dung chính

Chống lại sự phụ thuộc

Đây là 1 trong những nguyên tắc quan trọng trong phát triển phần mềm. Có rất nhiều framework thực hiện tốt được điều này như Ninject, Autofac, Stucture Map, MEF…
Trong bài viết này, mình không có tham vọng nêu rõ nguyên tắc lẫn cách sử dụng các framework, mà mình sẽ hướng dẫn từng bước chuyển đổi chương trình cho thật linh hoạt.
Bài toán: Có 2 loài động vật: sử tử và ngựa, sống trong rừng, Tazania hoặc sở thú. Mỗi con có duy nhất 1 phương thức là Running()
Ngựa sống trong rừng. Sử tử sống ở Tazania. Sở thú thì có cả 2 con, nhưng tại 1 thời điểm, họ chỉ cho phép 1 con thú chạy vòng vòng.
Theo cách viết thông thường, bạn sẽ viết cứng:
var forest = new Forest();
forest.Show();

Đây là lớp Forest
public class Forest
{
 private IAnimal _animal;

 public Forest()
 {
  _animal = new Horse();
  Console.WriteLine("---Forest---");
 }

 public void Show()
 {
  _animal.Running();
 }
}
Cách viết này có 1 điểm dở: Rừng bị phụ thuộc vào ngựa. Sau này muốn thay đổi thì phải vào sửa lớp Forest.

Cách 2

Ta viết lại lớp Tazania nhưng _animal không phụ thuộc vào lớp cố định
public class Tanzania
{
 private IAnimal _animal;

 public Tanzania(IAnimal animal)
 {
  _animal = animal;
  Console.WriteLine("---Tanzania---");
 }

 public void Show()
 {
  _animal.Running();
 }
}

Cách 3

Bạn sẽ sử dụng design Pattern Abstract Factory để giải quyết sự phụ thuộc.
Abstract Factory, đầy đủ là Abstract Factory pattern, là thiết kế mẫu hướng đối tượng trong việc thiết kế phần mềm cho máy tính, cung cấp một giao diện lớp có chức năng tạo ra một tập hợp các đối tượng liên quan hoặc phụ thuộc lẫn nhau mà không chỉ ra đó là những lớp cụ thể nào tại thời điểm thiết kế.
(Wikipedia)
Thay vì cài đặt, mình sẽ sử dụng AutoFac để đơn giản hóa vấn đề coding

static void RegisterAfrica()
{
 var builder = new ContainerBuilder();
 builder.RegisterType<Lion>().As<IAnimal>();
 Container = builder.Build();
}

static void RegisterAsia()
{
 var builder = new ContainerBuilder();
 builder.RegisterType<horse>().As<IAnimal>();
 Container = builder.Build();
}

static void ParticularExample()
{
 RegisterAfrica();
 using (var scope = Container.BeginLifetimeScope())
 {
  var zoo = new Zoo(scope.Resolve<IAnimal>());
  zoo.Show();
 }            
}
Để gọi loài động vật tương ứng, bạn gọi hàm Register().
Trong ví dụ này, có lẽ bạn chưa thấy được công dụng của việc chống lại sự phụ thuộc. Nhưng giả sử bạn viết 1 phần mềm. Giai đoạn đầu, bạn sử dụng LinQ, sau này chuyển qua Entity Framework, và nó được implement rất nhiều chỗ. Thông qua hàm Register() duy nhất, bạn có thể chuyển đổi dễ dàng mà không sợ bị lỗi. Viết theo cách 1, bạn phải sửa đổi tất cả các lớp, viết theo cách 2, bạn phải sửa đổi giá trị khi truyền vào hàm khởi tạo. Viết theo cách 3, bạn chỉ sửa hàm Register().
Hi vọng bài viết này sẽ hữu ích với các bạn
Demo: MediaFire

Nhận xét

Bài đăng phổ biến từ blog này

[ASP.NET MVC] Authentication và Authorize

Một trong những vấn đề bảo mật cơ bản nhất là đảm bảo những người dùng hợp lệ truy cập vào hệ thống. ASP.NET đưa ra 2 khái niệm: Authentication và Authorize Authentication xác nhận bạn là ai. Ví dụ: Bạn có thể đăng nhập vào hệ thống bằng username và password hoặc bằng ssh. Authorization xác nhận những gì bạn có thể làm. Ví dụ: Bạn được phép truy cập vào website, đăng thông tin lên diễn đàn nhưng bạn không được phép truy cập vào trang mod và admin.

ASP.NET MVC: Cơ bản về Validation

Validation (chứng thực) là một tính năng quan trọng trong ASP.NET MVC và được phát triển trong một thời gian dài. Validation vắng mặt trong phiên bản đầu tiên của asp.net mvc và thật khó để tích hợp 1 framework validation của một bên thứ 3 vì không có khả năng mở rộng. ASP.NET MVC2 đã hỗ trợ framework validation do Microsoft phát triển, tên là Data Annotations. Và trong phiên bản 3, framework validation đã hỗ trợ tốt hơn việc xác thực phía máy khách, và đây là một xu hướng của việc phát triển ứng dụng web ngày nay.

Tổng hợp một số kiến thức lập trình về Amibroker

Giới thiệu về Amibroker Amibroker theo developer Tomasz Janeczko được xây dựng dựa trên ngôn ngữ C. Vì vậy bộ code Amibroker Formula Language sử dụng có syntax khá tương đồng với C, ví dụ như câu lệnh #include để import hay cách gói các object, hàm trong các block {} và kết thúc câu lệnh bằng dấu “;”. AFL trong Amibroker là ngôn ngữ xử lý mảng (an array processing language). Nó hoạt động dựa trên các mảng (các dòng/vector) số liệu, khá giống với cách hoạt động của spreadsheet trên excel.