MVP - Model View Presenter

Giới thiệu

- Trong bài viết giới thiệu về mô hình MVC, chúng ta đã đề cập đến các nhược điểm của ngôn ngữ ASP. Có thể thấy hiện giờ ít trang web nào sử dụng công nghệ ASP cũ để phát triển nữa mà thay vào đó là các ngôn ngữ mới hơn, tiện ích hơn như PHP, ASP.NET, Java, v.v. Microsoft giới thiệu ngôn ngữ ASP.NET với điểm nhấn tách riêng các thành phần giao diện và xử lý dữ liệu bussiness logic bằng mô hình code-behind. ASP.NET có vẽ như là một lựa chọn tốt cho các ứng dụng web đơn giản, nhưng chính mô hình code-behind sẽ gây ra một số khó khăn cho các ứng dụng web vừa và lớn:

- Code-behind dường như được thiết kế để làm quá nhiều việc, nó vừa là một nơi để xử lý các event, kiểm soát các workflow trong chương trình và nó còn là một layer trung gian giữa dữ liệu bên dưới và giao diện phía trên. Người lập trình có thể viết mọi thứ trong code-behind và làm cho nó trở nên vô cùng rối rắm. Để cho code-behind làm quá nhiều thứ sẽ làm cho code của bạn khó kiểm soát và khó test (Unit Test). Trong những ứng dụng web lớn, người ta xem một design tốt khi nó giảm thiểu sự phụ thuộc lẫn nhau giữa các tầng (layer) và làm sao để cho code-behind càng đơn giản càng tốt. Với mô hình Model-View-Presenter, chúng ta sẽ thấy rằng code-behind được giữ cho vô cùng đơn giản và không hề dính dáng gì đến những xử lý trên giao diện Web.

- Một nhược điểm khác của code-behind là nó hầu như rất khó để sử dụng lại những xử lý giao diện (presentation logic) giữa những trang code-behind khác nhau nếu không đưa các xử lý đó ra các lớp Utility hay Helpers để tránh trùng lặp code. Tất nhiên để làm được điều đó cần một thời gian để tổ chức các lớp cho thich hợp. Tuy nhiên, nó thường dẫn chúng ta đến việc thiết kế các lớp một cách rời rạc và giống như khi sử dụng ASP. Trong một design tốt, mỗi class trong hệ thống nên có duy nhất một nhiệm vụ và mục đích rõ ràng, nếu chúng ta cần tạo ra một class chỉ để tránh trùng lặp code giữa 2 hoặc nhiều nơi khác thì đó là một dấu hiệu xấu, một thiết kế tồi.

- Và một nhược điểm cố hữu mà tôi thường nhắc đến là khả năng sử dụng Unit Test để test các lớp code-behind này. Các lớp code-behind đều kế thừa từ System.Web.UI.Page nên khó có thể viết các Unit Test một cách tự nhiên và thuận lợi được.

- Đã có nhiều kĩ thuật được tìm ra để giải quyết vấn đề của code-behind. Chẳng hạn như Castle Monorail project đã kế thừa những lợi điểm của Ruby-On-Rails và không sử dụng mô hình ASP.NET event. Thực ra cũng giống như ASP.NET MVC Framework, Castle Monorail hướng người lập trình đến cách phát triển ứng dụng Web theo MVC hơn là MVP, và khi áp dụng những framework này, chúng ta sẽ làm web ASP.NET theo một cách hoàn toàn khác, không có postback, không có server controls,... Khác với các framework hỗ trợ MVC, các framework hỗ trợ MVP là những giải pháp trong đó vẫn giữ mô hình event của ASP.NET nhưng hướng đến mục tiêu làm cho code-behind càng đơn giản càng tốt. Model-View Presenter sẽ giúp bạn làm được chuyện đó mà không cần dựa trên một framework nào cả. Đó cũng chính là lý do rất nhiều lập trình viên Web đã chọn MVP thay vì MVC trước khi có những framework hỗ trợ MVC như hiện nay.

- Bên cạnh các ASP.NET MVC Framework, Castle Monorail, hiện nay đã có những framework hỗ trợ MVP cho .NET như MVC# FrameworkNMVP Framework. Hi vọng tôi có thời gian tìm hiểu và chia sẽ với các bạn muốn quan tâm. Trong bài viết này, tôi sẽ trình bay khái quát lý thuyết suông về MVP; một sample code sẽ được giới thiệu trong bài tiếp theo.

Các bạn đang xem bài viết về Model View Presenter từ blog của Nguyễn Thoại (http://nthoai.blogspot.com)
Model-View-Presenter

- Nhiều người cho rằng MVP là một design biến đổi của MVC. Điểm khác nhau dễ thấy nhất là Presenter và Controller :bbpraroi: hehe đùa thôi... Trong mô hình MVP, các lớp View sẽ được sử dụng thông qua một Interface được định nghĩa trong .NET. Các lớp Presenter tương ứng sẽ sử dụng Interface này để đọc và ghi dữ liệu lên trên các View. Trong đa số các cách implement, một View sẽ có một Presenter tương ứng của nó. View sẽ khởi tạo Presenter cho nó và truyền cho Presenter này tham chiếu đến chính nó. Khi một event nào trên view được kích hoạt chẳng hạn như button_clicked, text_changed,.. bản thân lớp View sẽ không làm gì cả mà sẽ để cho lớp Presenter xử lý những sự kiện đó. Presenter sẽ đọc dữ liệu từ View (vì nó giữ một instance của View như là một member trong class) thông qua View Interface, thực hiện những xử lý ứng với Event được kích hoạt và set những thay đổi từ dữ liệu Model lên trên View thông qua View Interface.

- Trong môi trường .NET, cùng một Presenter có thể được sử dụng cho View trên web như các trang ASP.NET hoặc được sử dụng cho các Form trong Windows Form Application. Các Presenter đọc và ghi dữ liệu thông qua một Interface của .NET nên nó hoàn toàn độc lập với layer View. Chính nhờ cách làm này mà ta có thể áp dụng Unit Test cho các lớp xử lý Presenter rất dễ dàng và nó cũng chính là một trong những lợi ích lớn nhất của MVP cho khả năng tái sử dụng.



Model View Presenter Solution Structure


Cập nhật View

- Khi thành phần dữ liệu Model được cập nhật, View cũng sẽ phải được cập nhật để hiển thị những thay đổi. Quá trình cập nhật View có thể được thực hiện bằng nhiều cách khác nhau. Có lẽ cũng từ những cách này mà Model-View-Presenter được chia thành hai loại là Passive View và Supervising Controller.

- Trong mô hình Passive View, Presenter sẽ cập nhật view tương ứng bằng cách đọc dữ liệu trực tiếp từ Model rồi set lên View, do đó các lớp View sẽ không biết gì về thay đổi dữ liệu bên dưới. Hay nói cách khác chúng hoàn toàn bị động theo như trên gọi.

- Còn trong mô hình Supervising Controller, các lớp View sẽ tương tác trực tiếp với Model bên dưới để đọc dữ liệu mà không cần thông qua các lớp Presenter. Presenter sẽ cập nhật Model; nó chỉ thay đổi những control trên View trong trường hợp có những xử lý giao diện phức tạp mà không thể khai báo trước chẳng hạn như ẩn hiện control, đổi màu text,…

Passive View and Supervising Controller


- Quyết định dùng Passive View hay Supervising Controller thường dựa trên nhu cầu test tự động của ứng dụng. Nếu bạn muốn làm một ứng dụng có thể test tự động dể dàng và cover hầu hết các xử lý bên trong thì Passive View là một lựa chọn thích hợp, mọi UI logic đều được test bằng cách viết lớp test cho các Presenter. Mặt khác, nếu bạn thích code đơn giản hơn thì Supervising Controller có vẻ là một lựa chọn thích hợp hơn. Đối với những thay đổi đơn giản trên giao diện, bạn cũng không cần đưa những xử lý cho các thay đổi đó vào lớp Presenter. Khi chọn lựa giữa Passive View và Supervising Controller, bạn nên cân nhắc các điều sau đây:

  • Cả hai cách đều cho phép bạn tăng khả năng test tự động cho các xử lý giao diện (presentation logic)
  • Passive View thường cung cấp khả năng test cao hơn Supervising Controller bởi vì tất cả các xử lý giao diện được đặt trong các lớp Presenter.
  • Supervising Controller sẽ đỡ phải code nhiều như Passive View bởi vì Passive View không cần thực hiện những cập nhật đơn giản cho View.

Tương tác với dữ liệu

- Bạn cần phân biệt rõ Model với Domain, hai khái niệm này hoàn toàn khác nhau. Chúng ta có thể implement các lớp tương tác với dữ liệu bằng nhiều cách khác nhau. Trong một số trường hợp, có thể bạn sẽ phải sử dụng Observer Pattern cho các Presenter và Model. Nó sẽ giúp cho Presenter nhận những events từ Model khi có sự thay đổi và từ đó cập nhật thay đổi đó lên trên View. Thông thường, người ta sẽ làm ra các lớp Service/Manager, các lớp này sẽ đóng vai trò như các lớp Bussiness Logic trong layer Model để giúp Presenter tương tác với database bên dưới:

MVP Tiers


Các nhược điểm của MVP

  • Có nhiều lớp, nhiều layer phải implement; có nghĩa độ phức tạp của ứng dụng sẽ tăng.
  • Bạn phải nghĩ ra một cách để kết hợp giữa các Views và các Presenters. Trong ASP.NET thì các lớp Code-Behind sẽ implement một interface IView nào đó và sử dụng một member Presenter.
  • Mô hình Model không biết gì về Presenter. Vì thế nếu dữ liệu Model bị thay đổi từ một chương trình khác thay vì bởi Presenter thì phải nghĩ ra một cách để Presenter biết. Các bạn có thể implement chức năng này nếu cần bằng cách sử dụng các events, hoặc tham khảo thiết kế Observer Pattern.



Trong bài sau tôi sẽ trình bày một sample cho Supervisinng Controller.:bbpxtay:

ASP.NET MVC Project templates cho VS.NET 2005

- Để có thể tạo được project web ASP.NET với mô hình MVC framework, các bạn phải download ASP.NET MVC Preview 3 Visual Studio Templates và chỉ có thể cài được khi bạn đã có VS.NET 2008 hoặc VS.NET Express 2008. Đối với những bạn chỉ có VS.2005 trong máy thì thật là bực mình vì …:bbpcuoi3: làm biếng đi mua đĩa VS.2008 mà lại muốn test ngay xem MVC trong ASP.NET như thế nào. Đối với một số người thì không thể có VS.NET 2008 để sử dụng vì bản quyền. Tôi đã táy máy để chuyển những template từ trang CodePlex để có thể install và chạy được với VS.NET 2005.:bbpraroi:

Bạn có thể download template cho VS.NET 2005 ở link sau:

1st mirror: ASPNET_MVC_Project_Template_for_VSNET_2005.html


Hoặc ở link sau


2nd mirror: ASPNET_MVC_Project_Template_for_VSNET_2005.html



Tuy nhiên có một số điều lưu ý:

- Nếu bạn vừa cài VS.NET 2005 và VS.NET 2008 thì tất nhiên cũng chẳng cần install cái setup của tôi làm gì. Khi bạn cài bản template của Codeplex, các template mặc định sẽ được chép vào các thư mục của VS.NET 2005 và mặc định cả 2 version đều có thể hiểu được các template này. Tuy nhiên template của CodePlex sẽ không chạy được cho VS.NET 2005 vì project được tạo ra từ template này chỉ hiểu được trên VS.NET 2008 (cú pháp C# 3.0). Vì vậy nếu như bạn muốn install phiên bản riêng cho VS.NET 2005 thì hãy bỏ check các Item Template và chỉ chọn install 2 project template ở cuối cùng như trong hình. Nếu bạn vẫn chọn và install, trình install sẽ hỏi bạn có chép đè file có sẵn từ lần install trước hay không, và bạn có thể chép đè vẫn không sao vì các item template có thể hiểu được trên cả VS.NET 2005 và VS.NET 2008.:bbpskien:

ASP.NET MVC Framework   project template for VS.NET 2005

Hình 1: Bạn có thể chọn những mục để install.

- Tôi đã chỉnh sửa một số nơi trong template gốc của CodePlex để project tạo ra có thể build được trên VS.NET 2005 cụ thể là sửa trong file global.asax.cs. Trong phần routing ở VS.NET 2008 có hỗ trợ các extension API mà VS.NET 2005 không thể hiểu được buộc lòng tôi phải đổi sang kiểu code truyền thống:bbpbuon::


ASP.NET MVC Framework project template for VS.NET 2005

Hình 2: Đổi sang kiểu code truyền thống để có thể build.

- Và sau khi install xong, các bạn sẽ thấy các template mới khi muốn tạo project mới:

ASP.NET MVC Framework project template for VS.NET 2005

Hình3: Project templates sau khi install



Trong mấy ngày tới, tôi sẽ nghiên cứu và chế ra cái template có sẵn Unit Test.:bbpsdieu2:

Posted in Labels: , , | Post a comment 17 comments

ASP.NET và MVC Framework

ASP.NET Model View Controller Framework

- Ai từng sử dụng qua ngôn ngữ ASP cũng biết rằng khá bất tiện khi phải xử lý code giao diện chung với những xử lý bussiness logic. Những xử lý để đọc dữ liệu database viết xen kẽ với những phần code định dạng HTML làm cho ứng dụng web rất khó bảo trì và khó tái sử dụng. Sau khi version 4.0 của IIS ra đời năm 1997, Bác Bill cùng các đồ đệ tiếp tục nghiên cứu một mô hình web application để giải quyết vẫn đề trên của ASP: tách rời giữa phần hiển thị và phần nội dung. Sau 4 năm nghiên cứu với một loạt những phiên bản beta ở các năm 2000 và 2001, ASP.NET 1.0 đã được công bố vào tháng 1 năm 2002, sau đó là version 1.1 ở tháng 4 năm 2003. Mô hình code-behind của ASP.NET đánh dấu một bước tiến so với người anh em ASP, nó khuyến khích người viết web trên nền .NET xây dựng những ứng dụng với sự tách bạnh rõ ràng giữa các thành phần hiển thị và nội dung mặc dù vẫn có thể viết theo style của ASP, mọi xử lý viết thẳng vào file aspx, ascx. Trên lý thuyết, mô hình này sẽ giúp những web designer chủ động thiết kế ra giao diện của ứng dụng mà không sợ ảnh hưởng đến những phần code xử lý bên dưới. Điều này dường như giống với ý tưởng tách rời giữa controller và view trong mô hình Model-View-Controller framework.

- Trong một số bài viết về cách implement MVC cho ASP.NET, các tác giả thường cho rằng Code Behind của 1 trang ASP.NET là controller, các file aspx, ascx chính là các View. Theo tôi điều này chỉ đúng một phần vì các nguyên nhân sau:

1/Với mô hình Code Behind, đúng là đã có sự tách riêng giữa phần hiển thị (aspx, ascx) và các xử lý bussiness logic. Tuy nhiên người lập trình chỉ có thể làm được chuyện tách riêng phần View và Controller. Trong khi phần Model nếu không làm khéo sẽ vẫn dính chặt với vần controller và chẳng dễ test nó chút nào. Nếu bạn viết code lấy dữ liệu từ database ngay trong file code behind của 1 trang thì rõ ràng Model và Controller của bạn dính thành 1 cục và không thể test được bằng Unit Test. Như vậy người không biết sẽ vô tình làm code của mình khó test, khó bảo quản và khó sử dụng lại.

2/Các lớp Code Behind của ASP.NET đều kế thừa từ System.Web.Page, như vậy controller theo kiểu này cũng không thể dùng Unit Test để test các xử lý bussines logic. Đó là điều mà các fan của Unit Test không thể chấp nhận được. Ngoài ra, với sự phụ thuộc vào namespace System.Web như vậy, những xử lý của bạn sẽ không thể sử dụng lại khi muốn đổi một ứng dụng web sang ứng dụng windows form.

- Ngoài các lý do trên, có 1 điều nữa giúp tôi khẳng định Mô hình Code Behind của ASP.NET không theo MVC, đó chính là sự ra đời của framework ASP.NET MVC gần đây và một số framework MVC khác cho ASP.NET.

- ASP.NET MVC Framework là một Model-View-Controller framework được Microsoft thêm vào bộ ASP.NET. Nó cho phép người làm phần mềm xây dựng những Web application theo ý tưởng của MVC, gồm 3 thành phấn Model, View và Controller. Một Model tượng trưng cho một trạng thái của ứng dụng. Thông thường, một model sẽ maps với một table trong cơ sở dữ liệu, những record trong table đó sẽ tượng trưng cho trạng thái của table đó. Còn một Controller sẽ handle những tương tác của người dùng với ứng dụng và cập nhật giá trị cho Model. Một View sẽ lấy những dữ liệu cần thiết của Model và hiển thị ra giao diện.


ASP.NET Model View Controller Framework Project Template


- ASP.NET MVC Framework tách rời các models, các views và các controllers của MVC bẳng cách dùng các Interface (trong ngôn ngữ lập trình), bằng cách đó giúp cho các thành phần này có thể test độc lập với nhau. View engine trong ASP.NET MVC framework chính là các trang aspx, ascx để hiển thị giao diện. Tuy nhiên, những tương tác của người dùng lên trang web sẽ được truyền thẳng cho controller mà không thông qua cơ chế postback truyền thống. Với ASP.NET MVC framework, chúng ta còn có thể làm được 1 trang web với Friendly-URL mà không phải mất công code những implement phức tạp như trước đây. ASP.NET MVC Preview 3 Release vừa mới được công bố hồi tháng 5/2008 với nhiều feature mới hứa hẹn nhiều điều hấp dẫn để tìm hiểu cho những lập trình viên như chúng ta.




Các bạn có thể tự tìm hiểu những resource về ASP.NET MVC Preview3 tại các link sau:

http://www.codeplex.com
http://www.asp.net
http://weblogs.asp.net/scottgu

Posted in Labels: , , | Post a comment 2 comments

MVC Model View Controller

- Mấy tuần nay tôi đang tìm hiều về các pattern thiết kế giao diện và đã gặp nhiều vướng mắc. Một số đã tự giải quyết được, một số vẫn còn tồn đọng. Vì vậy tôi cũng muốn chia sẽ những gì mình đã tìm hiểu với mọi người. Tôi quyết định dịch và viết bài từ mô hình ra đời lâu nhất và được nhiều người biết đến nhất, đó là mô hình MVC. Ban đầu tôi đã định không tìm hiểu về MVC và đi vào những thiết kế mới nhất như MVP nhưng thực ra MVC vẫn còn rất phổ biến hiện nay. (Cám ơn Tính nai oan oan cho các thông tin về MVC và Monorail) Vì vậy, trong những loạt bài sau tôi sẽ viết nhiều về pattern đang phổ biến hiện nay như MVP và các ví dụ thực tế của nó. Phần lớn sẽ là bài dịch và sửa đổi cho dễ hiểu, hiện nay vẫn chưa đủ trình độ để sáng tạo cái gì cả.:bbpbuon:

- Có thể nói rằng các chương trình dù là Win Application hay Web Application đều gồm hai thành phần chính là giao diện và dữ liệu. Các ứng dụng chúng ta tạo ra sẽ đọc dữ liệu từ nơi lưu trữ và hiển thị lên cho người dùng thấy. Sau khi người sử dụng chương trình thao tác với ứng dụng và thay đổi giá trị dữ liệu, chương trình sẽ lưu các thay đổi đó xuống nơi lưu trữ. Do luồng thông tin chính của các ứng dụng sẽ truyền từ nơi lưu trữ lên trên phần hiển thị và ngược lại nên người có thể cho rằng nên có cách nào đó thiết kế hai thành phần dữ liệu và giao diện cùng với nhau để giảm thiểu việc coding và tăng performance. Dù không cố tình làm như vậy nhưng đa số những bạn mới viết chương trình cơ sở dữ liệu lần đầu tiên thường không biết nên sẽ làm theo cách này. Cách làm như vậy có một số vấn đề nghiêm trọng. Một trong các vấn đề đó là việc giao diện thường có xu hướng thay đổi nhiều hơn so với dữ liệu lưu trữ. Hơn nữa, những xử lý tính toán (business logic) trong chương trình cũng là một thành phần thường xuyên thay đổi trong suốt quá trình phát triển phần mềm. Nếu chương trình được xây dựng theo kiểu trộn lẫn code của các thành phần data access, business logic và presentation thì sẽ rất khó bảo trì sửa đổi cũng như khả năng sử dụng lại. Chính vì mục đích tăng tính độc lập giữa các thành phần trong ứng dụng và để giải quyết những trở ngại trên, người ta đã nghĩ ra nhiều mô hình và cách thiết kế ứng dụng rất hiệu quả. Kể từ những năm 70, mô hình MVC được nghĩ ra để giải quyết một số vấn đề trên.

Đặt vấn đề:

- Khi lần đầu tiên viết chương trình đọc dữ liệu từ database và hiển thị lên form, tôi đã viết chương trình kiểu gom chung phần xử lý giao diện và truy xuất dữ liệu làm một. Có nghĩa là tôi tạo ra câu query sql ngay trong code của lớp giao diện. Cách làm này rất không hợp lý vì khi sửa đổi cấu trúc bảng trong cơ sở dữ liệu thì câu query sql sẽ cần phải đổi, dẫn đến phải sửa lớp giao diện. Khi cần đổi database khác thì gần như phải viết lại từ đầu. Như vậy gom chung giữa giao diện và dữ liệu là không nên, và ai cũng biết điều đó.

- Liệu có một cách nào chúng ta có thể chia nhỏ chương trình thành nhiều module để tiện thay đổi, bảo trì?


Giả sử người ta có các yêu cầu sau:

- Giao diện của ứng dụng có xu hướng thay đổi nhiều hơn là những thay đổi business logic của chương trình, đặt biệt đối với những ứng dụng Web. Ví dụ như cùng một trang Web hiển thị sản phẩm có thể sẽ được yêu cầu thay đổi nhiều lần về cách bố trí sản phẩm, màu sắc bố cục trong khi cách để lấy thông tin sản phẩm từ database sẽ không cần sửa đổi. Hơn nữa, một trong những tiện lợi của ứng dụng Web là người ta có thể thay đổi giao diện vào bất cứ lúc nào mà không cần người dùng phải install cài đặt gì cả. Nếu như những đoạn code xử lý giao diện và xử lý business logic bên trong chương trình được viết chung với nhau, bạn sẽ phải thay đổi những lớp dùng để xử lý business logic mỗi khi cần thay đổi giao diện. Mà khi xử lý business logic của ứng dụng bị thay đổi thì có thể sẽ gây ra các lỗi không mong muốn nên phải test mọi thứ lại từ đầu cho dù đó chỉ là một thay đổi nhỏ về giao diện. Như vậy ta có một nhu cầu về việc tách riêng giữa giao diện và các xử lý business logic.

- Trong một số ứng dụng, chương trình sẽ hiển thị cùng một dữ liệu bằng nhiều cách khác nhau. Ví dụ như chúng ta cần làm một loạt các biểu đồ khác nhau hiển thị giá chứng khoán, các biểu đồ này được hiển thị cùng lúc. Nếu người dùng thay đổi dữ liệu trên một màn hình nào đó thì hệ thống phải cập nhật thay đổi đó trên các màn hình còn lại. Ta có một nhu cầu về tự cập nhật giao diện khi có những thay đổi trong dữ liệu.

- Để thiết kế giao diện HTML đẹp và hiệu quả cần những kĩ thuật đặt biệt, có khi cả năng khiếu về mĩ thuật mà không phải một lập trình viên nào cũng có được. Vì vậy trong những dự án lớn thường có những người design giao diện riêng và công việc của họ chỉ là thiết kế layout, còn lập trình viên sẽ thực hiện các xử lý business logic của ứng dụng. Do đó nhu cầu cho việc tách rời phần design giao diện và phần lập trình được đặt ra để tăng hiệu quả cho quá trình làm phần mềm.

- Có một yêu cầu khác được đặt ra như sau: những thao tác trên giao diện thông thường sẽ gồm có hai phần: hiển thị và cập nhật. Thành phần hiển thị sẽ lấy dữ liệu từ nơi lưu trữ, định dạng lại nếu cần thiết và hiển thị lên màn hình. Khi người sử dụng thực hiện một số thao tác, những gì thay đổi sẽ được thành phần cập nhật gọi thành phần xử lý business logic để cập nhật các thay đổi đó xuống nơi lưu trữ. Như vậy thành phần hiển thị sẽ tự nó thực hiện việc lấy thông tin, trong khi những thao tác của người dùng sẽ được xử lý bởi một thành phần khác.

- Trong các ứng dụng Web, khi bạn click vào một link trên 1 trang, một thao tác ứng với link đó sẽ được thực hiện đồng thời một trang mới sẽ được hiển thị. Trong nhiều trường hợp, trang web cần hiển thị sau cùng sẽ không liên quan trực tiếp đến thao tác được gọi khi click vào link ở trang trước. Ví dụ: trong những trang Web mua bán trực tuyến, khi muốn xem danh sách những món hàng mình muốn mua trước khi thanh toán, bạn sẽ click vào phần giỏ hàng. Một danh sách những món hàng sẽ hiện ra kèm với các link hoặc button xóa chúng khỏi giỏ hàng. Nếu bạn đổi ý và muốn bỏ đi một món nào đó thì bạn sẽ click vào link hoặc button tương ứng. Sau đó, giỏ hàng sẽ lại hiện ra với danh sách những món hàng mới mà không có món bạn vừa xóa. Vì vậy, ứng dụng phải hiển thị lại cùng 1 trang với cùng một danh sách nào đó sau khi thực hiện hai thao tác khác hẳn nhau trong cùng một HTTP request. Vậy có một yêu cầu là nhiều xử lý phức tạp sẽ được thực hiện trong cùng một request.

- Ngày nay, giao diện của một ứng dụng nên được độc lập với thiết bị. Nếu bạn muốn ứng dụng Web của mình có thể được hiển thị nhanh và đẹp trên các thiết bị di dộng thì bạn phải sửa đổi nhiều ở phần giao diện và chắc chắn là những business logic sẽ không cần thay đổi gì cả. Một sự tách biệt rõ ràng giữa hai thành phần này sẽ giúp bạn đạt được yêu cầu đó vài giảm thiểu những rủi ro khi phải thay đổi business logic do sai lầm khi thiết kế lúc đầu. Vậy dẫn đến yêu cầu về thiết kế ứng dụng để dễ dàng hỗ trợ nhiều dạng thiết bị khác nhau chứ không riêng gì máy tính.

- Và cuối cùng, để phần mềm của bạn có thể được test một cách toàn diện đôi khi không khả thi và rất mất thời gian. Hiện nay người ta có thể sử dụng Unit Test để test các lớp business logic nhanh chóng chính xác và tự động trong hầu hết trường hợp. Vì thế càng làm cho những xử lý tách rời khỏi phần giao diện sẽ giúp chương trình của bạn dễ viết code test hơn. Vậy yêu cầu thiết kế ứng dụng cho dễ test bằng code cũng được đặt ra.

MVC sẽ đạt được mọi yêu cầu trên:

- Mẫu thiết kế Model-View-Controlller (MVC) tách rời phần dữ liệu domain, module hiển thị và những xử lý thao tác của người dùng thành ba nhóm lớp (class) riêng biệt:

Model: là những gì liên quan đến dữ liệu của ứng dụng. Model sẽ chịu trách nhiệm thao tác trực tiếp với database như truy xuất, cập nhật, thêm mới. Model sẽ lấy thông tin và trả về cho View, nó cũng sẽ chịu trách nhiệm thông báo cho Controller những thay đổi dữ liệu nếu có. Bạn có thể xem Model bao gồm các lớp DAL (Data Access Layer) và các lớp Domain.

View: View sẽ chịu trách nhiệm hiển thị thông tin như tên của nó. Ta có thể xem View như các trang web, hoặc các form trong ứng dụng windows.

Controller: là những lớp sẽ lắng nghe những thao tác chuột và bàn phím từ người dùng, nó sẽ tác động đến Model và View để thay đổi khi cần thiết.

Hình dưới mô tả mối quan hệ giữa Model, View và Controller, Model sẽ không biết gì về View và
Controller.

Model View Controller Class Structure


Hình: MVC Class Structure

- Theo như hình trên thì ta thấy cả View và Controller đều phụ thuộc và có thể gọi đến Model. Tuy nhiên, Model lại hoàn toàn độc lập với View và Controller. Điều này là một trong những lợi ích chính của mô hình MVC khi tách rời các thành phần Model View và Controller. Sự độc lập của Model giúp chúng ta build và viết code test cho nó mà không ảnh hưởng hoặc phụ thuộc đến những lớp hiển thị. Ngoài ra, sự tách rời View và Controller ra hai nhóm lớp như trên là một thuận lợi thứ hai đối với những ứng dụng có nhiều người dùng. Ví dụ như trong một số cách làm, người ta có thể lập trình phần kiểm tra quyền (Role) ngay trong phần xử lý giao diện. Khi theo cách làm MVC, người ta sẽ phải tách riêng phần kiểm tra quyền ra khỏi phần hiển thị và nó hoàn toàn thuận lợi khi cần sửa đổi hoặc thêm những trang mới.

Những lợi ích về test khi áp dụng MVC

- Sự dễ dàng trong viết code test là một thuận lợi khi áp dụng MVC. Test những component của chương trình trở nên rất khó khăn khi chúng phụ thuộc chặt chẽ vào nhau, đặc biệt đối với những thành phần giao diện. Để test giao diện của một phần mềm, tất nhiên bạn phải qua các bước cài đặt và đôi khi điều đó trở nên rất mất thời gian khi chỉ để test một chức năng đơn giản. Tệ hơn khi xảy ra lỗi, chúng ta sẽ rất khó để phát hiện lỗi ở phần nào. Đó là lý do tại sao chia nhỏ các thành phần chức năng là một trong những chiều hướng chính của các thiết kế quan trọng. MVC chia nhỏ các vấn đề như lưu trữ, hiển thị và cập nhật dữ liệu thành 3 nhóm components, những component này có thể được test độc lập với nhau.

- Ngoài vấn đề về sự phụ thuộc, giao diện của phần mềm cũng rất phức tạp khi muốn test. Người ta thường sử dụng người thật để test giao diện, hoặc sẽ phải viết những script test để giả lập những thao tác của con người. Để viết những script này thường rất mất thời gian và phức tạp. MVC KHÔNG giải quyết được vấn đề về test giao diện, NHƯNG nó tách rời phần dữ liệu Model ra khỏi những xử lý hiển thị và cho phép MODEL có thể được test độc lập với phần hiển thị và điều đó sẽ giảm thiểu những test case liên quan đến giao diện.

Ý kiến của Nguyễn Thoại:

- Tôi đã không dịch và đưa vào những dạng biến đổi của mẫu MVC vào bài này vì không muốn các bạn cảm thấy rối thêm, cũng không đưa vào những lợi ích và giới hạn của MVC. Lợi ích thì tất nhiên đã được đề cập tới ở trên nên cũng không cần tổng kết lại làm gì, còn giới hạn chính là tính phức tạp. Cũng như những bài viết trước, các Pattern luôn phức tạp nhưng khi chịu khó một chút thì về sau sẽ được những lợi ích lớn.

- Các bạn có thể đặt câu hỏi: áp dụng MVC vô ASP.NET như thế nào. Có ví dụ code sample nào không. Xin thưa là có trang ví dụ ở đây, nhưng cá nhân tôi vẫn còn nghi ngờ tính đúng đắn của nó. Sắp tới, tôi sẽ viết thêm một số bài nữa liên quan đến việc áp dụng MVC trong.NET để tìm hiểu những vấn đề tôi còn nghi ngờ. Trong bài viết này không có ví dụ vì tôi sẽ dành phần code sample cho các bài sau. Hi vọng qua bài dịch này các bạn có được khái niệm MVC là cái gì, và lợi ích của nó như thế nào và khoan hãy nghĩ đến cách áp dụng. Cũng giống như những pattern khác (ở các bài viết sau), MVC được nghĩ ra với mục đích tách rời các thành phần quan trọng trong ứng dụng để tăng tính dễ bảo trì, dễ test tự động và khả năng sử dụng lại. Cùng một mục đích như vậy nhưng các mẫu pattern khác như MVP sẽ có cách thực hiện và cách cài đặt khác. :bbpraroi:


Liệu mô hình ASP.NET của Microsoft với các trang aspx và code behind tách rời có phải là một implement MVC? Ở bài sau tôi sẽ trả lời câu hỏi đó và giới thiệu khái quát về một framework MVC Framework cho ASP.NET.

Posted in Labels: , , | Post a comment 2 comments

Phỏng vấn 2 mẫu thiết kế Abstract Factory và Factory Pattern

Interview Abstract Factory and Factory Method (Design Patterns)



Nguyễn Thoại
: Chà chà, chào hai anh, đây là lần đầu tiên blog của iem phỏng vấn hai anh, hai anh cảm thấy thế nào.

Factory Method: Tôi ko biết sao hay bị gộp chúng với cha Abstract Factory. Đều là factory pattern không có nghĩa chúng tôi không được có những buổi phỏng vấn riêng.:bbpcaycu:

Nguyễn Thoại: Ấy ấy, đừng tự ái, em muốn phỏng vấn cả hai anh cùng nhau để giúp đọc giả phân biệt được ai là ai. Hai anh có nhiều điểm giống nhau, và em có nghe vài phàn nàn rằng người ta thỉnh thoảng bị rối và không thể phân biệt được 2 người.

Abstract Factory: Ừ đúng đấy, đã có lúc tôi bị nhầm lẫn là cha Factory Method, và tôi biết ổng cũng bị giống như tôi. Hai tụi tôi đều giỏi trong việc giảm sự phụ thuộc giữa chương trình với những cài đặt cụ thể; nhưng mỗi người chúng tôi lại có những cách làm riêng nên thỉnh thoảng dân lập trình lại cảm thấy rối và không thể xác định được phải dùng cách nào.:bbpcuoi3:

Factory Method: Ấy, người ta vẫn phân biệt được tôi mà. Nói chung, tôi dùng các lớp để tạo ra products, còn cha dùng những đối tượng; hai cách đó hoàn toàn khác nhau nhé.

Nguyễn Thoại: Ừ em có tìm hiểu về hai anh rồi mà vẫn còn rối đây này, anh có thể nói thêm về khoản này không, anh Factory Method?:big_smile:

Factory Method: Ok, Cả cha Abstract Factory và tôi đều tạo ra các products, các objects, đó là việc chúng tôi phải làm. Nhưng tôi làm nhờ vào sự kế thừa (inheritance) …

Abstract Factory: … còn tôi làm nhờ vào sự kết hợp các đối tượng.

Factory Method: Đúng thía, nghĩa là nếu muốn tạo ra các đối tượng bằng cách Factory Method, người ta cần phải extend một lớp và override lại hàm tạo “factory method”.

Nguyễn Thoại: …rồi factory method sẽ làm cái gì?

Factory Method: Tất nhiên là tạo ra 1 object roài, anh đã từng viết bài về tôi mà giờ còn hỏi hả. Ý tưởng của tôi, Factory Method Pattern, là sẽ sử dụng các lớp con để sinh ra 1 đối tượng mong muốn. Bằng cách đó, người dùng sẽ chỉ cần biết đến lớp trừu tượng như gia cầm, và các lớp con cụ thể sẽ lo về các kiểu gà, kiểu vịt, kiểu ngan. Vì vậy, nói theo cách khác, tôi giúp chương trình độc lập với các kiểu (type) cụ thể đó.:bbpskien:

Abstract Factory: Ý tưởng của tôi cũng giống giống vậy đó, nhưng chỉ là làm theo một cách khác…

Nguyễn Thoại: Tiếp đi anh Abstract Factory … vừa rồi anh có đề cập đến cách kết hợp các đối tượng?

Abstract Factory: Ờ,cách của tôi thế này: Tôi tạo ra một kiểu trừu tượng (abstract type) để dùng vào việc tạo ra một nhóm những products khác. Khi đó, những lớp con của kiểu trừu tượng sẽ xác định cách tạo ra các products này. Để áp dụng được ý tưởng của tôi, bạn phải tạo ra một instance của một trong các lớp con trên (instance này là 1 factory) và đưa nó vào chỗ cần thiết trong code. Vì thế, giống như Factory Method, những nơi sử dụng factory của tôi sẽ hoàn toàn độc lập với những produtcts cụ thể.

Nguyễn Thoại: Oh yè, tôi biết rồi, một lợi ích nữa của cách này là anh đã nhóm các products tương tự nhau lại, có đúng không?

Abstract Factory: Đúng roài cưng à.:bbpchao:

Nguyễn Thoại: Bây giờ người ta cần bổ sung thêm một product nữa vô nhóm các products mà anh có thể tạo ra. Vậy không cần phải thay đổi gì hết huh?

Abstract Factory: Hèm, trường hợp này thì tôi phải thay đổi chút ít, nhiều người không thích lắm ở điểm này.

Factory Method: hĩ hĩ:bbpcuoi3:

Abstract Factory: Cười gì cha nội?:bbpbuon:

Factory Method: Cười chứ sao ko cười, làm vậy quá mất công chứ gì nữa. Cha thay đổi có nghĩa là người dùng phải đi mà đổi tất cả các lớp con roài? (các lớp con ở đây là các factories)

Abstract Factory: Đúng, nhưng cần phải làm như vậy vì tôi có khả năng tạo ra nhiều kiểu product khác nhau, trong khi người ta xài cách của anh khi họ cần tạo ra một kiểu product nào đó thôi, vì thế anh không có cồng kềnh như tôi, anh chỉ cần một method duy nhất.:bbpnodo:

Nguyễn Thoại: Anh Abstract Factory bớt nóng, tôi nghe đồn rằng anh thường sử dụng nhiều hàm factory method theo cách của anh Factory Method để tạo các đổi tượng bên trong những factories của anh, điều đó có đúng ko?

Abstract Factory: Đúng đó em, anh thừa nhận điêu này. Những lớp factory con thường dùng các factory method để tạo các products tương ứng. Trong trường hợp này, các factory method được dùng thuần túy để tạo ra các products.

Factory Method: … còn tôi dùng hàm factory method để tạo ra product cụ thể mà người ta muốn, người dùng sẽ không biết cái gì được tạo ra, họ chỉ cần gọi hàm.

Nguyễn Thoại: Dường như hai anh làm rất tốt công việc của mình. Tôi chắc rằng đọc giả đã có được lựa chọn của mình. Sau cùng, những factories của 2 anh quả thật rất hữu ích, đọc giả của tôi sẽ sử dụng chúng trong các tình huống thích hợp nhất. Các anh đều đóng gói (encapsulate) quá trình tạo ra đối tượng để giúp chương trình độc lập và giảm phụ thuộc với những kiểu cụ thể, việc làm này thật đáng tuyên dương. Cám ơn hai anh, hai anh có lời gì trước khi chào tạm biệt đọc giả không ạ?:bbpbtay:

Abstract Factory: Cám ơn. Hãy nhớ đến tôi, Abstract Factory, và sử dụng tôi bất cứ khi nào bạn cần cùng một lúc tạo ra nhiều loại products, và khi bạn muốn chắc chắn những nơi sử dụng sẽ không cần biết đến những lớp cụ thể khi cần làm việc này.:bbpskien:

Factory Method: Còn tôi là Factory Method, hãy sử dụng tôi để làm cho chương trình của bạn độc lập với những lớp cụ thể mà bạn cần tạo 1 đối tượng, hoặc khi bạn không biết sau này sẽ cần đến những lớp con nào nữa. Khi cần sử dụng tôi, hãy tạo tạo ra subclass (1 factory implement 1 kiểu abstract) và implement factory method cho chính bạn.:bbpraroi:



(Page 158-162 of Head First – Design Pattern)



Abstract Factory and Factory Method (Design Patterns)





10 điều bạn sẽ phải chấp nhận nếu làm việc trong ngành IT

1/Ở những ngành khác thì nữ vừa nhiều vừa xinh đẹp, ngành IT thì ngược lại.

- Điều này thì tự ai đã và đang học CNTT ở các trường ĐH thì biết rồi. Không riêng gì trong ngành CNTT mà trong những ngành kĩ thuật thì số lượng nữ giới cũng rất thấp. Tuy nhiên so với các ngành như Cơ Khí, Điện Tử thì tỉ lệ nữ giới học CNTT cũng còn khá cao. Nhưng khi học xong và đi làm thì tỉ lệ nữ giới làm lập trình lại càng giảm, đa số các bạn âý làm QC, DB, BA, … .Ở nhóm tôi khoảng 20 người chỉ có mỗi 2 dev, 2 QC là nữ, còn lại toàn đực rựa. Tuy nhiên cũng an ủi là trong cty vẫn có nhiều chị em xinh lắm hĩ hĩ nhưng không làm ở bộ phận lập trình. Thiếu thốn này thường dẫn đến điều thứ 2. :feel_good:

2/Xác suất phải lập gia đình với người cùng ngành rất cao.

- Nghe có vẽ như hơi mâu thuẫn, đã ít nữ thì làm sao xác suât này cao được. Thế nhưng những người làm IT thì kể từ lúc đi làm thường nhìn máy tính nhiều hơn giao tiếp với ngưòi thật nên sẽ ăn nói kém, giao tiếp kém, cơ hội gặp những phụ nữ khác ngành cũng ít hơn những người làm ở ngành khác nên trời kiu ai nấy dzạ :bbpbuon:. Tuy nhiên chúng ta thường quen nửa cuộc đời của mình từ trong trường ĐH hoặc ở nơi làm việc nên điều này có thể cũng đúng với những người làm ở các ngành khác. Dù những người làm ở ngành IT chúng ta thường được cái thông minh, nhưng 2 người thông minh thì sinh con ra chưa chắc thông minh nên đây cũng là một hiểm họa tiềm tàng. Hơn nữa, 2 người cùng ngành IT giờ gặp nhau ngoài nói chuyện bug, code thì chán chết. Phải chi chàng kể chuyện bug, nàng hỏi bug là gì huh anh thì có thú vị ko nhẩy :bbpdthu:

3/Bạn sẽ bị yếu đi.

- Điều này không có gì phải bàn cãi. Thứ nhất ngồi nhiều … thì bụng và mông sẽ to. Bụng càng to càng khó làm... nhiều thứ và tuổi thọ giảm. Ngồi nhiều thì còn có thể gây ra nhiều bệnh tế nhị khác. Ngoài 2 cái bệnh đằng trước và đằng sau thì còn bệnh ở mắt do nhìn quá nhiều. Đa số người làm IT xung quanh ta đều bị cận thị. Gõ máy tính thường xuyên sẽ ảnh hưởng đến tim, rê chuột thường xuyên sẽ thoái hóa cổ tay. Ngoài ra cột sống sẽ bị chai hoặc mọc gai do cái tật ngồi nhiều hơn đứng của công việc này. Ngoài ra, những ngưòi làm IT thường có thói quen làm việc, sinh hoạt ban đêm. Cái giờ đáng lẽ những người trong những ngành khác làm cái việc mà ai cũng biết là việc gì đấy thì người trong ngành IT lại gõ gõ, click click và nó thường gây ra bệnh đau bao tử. Tay chân ít hoạt động nên con người thường cảm thấy mỏi mệt, lười vận động, thậm chí cả lười tắm nên đừng thắc mắc tại sao một số SV ở ngành IT thường hay ở dơ. Nói chung làm cái nghề này nếu ko chịu sinh hoạt … điều độ thì đừng mong thọ.:bbpskien:

4/Bạn sẽ thường xuyên bị làm phiền bởi người quen.

- Đây là một trong những điều tệ hại và khó chịu nhất mà bạn sẽ gặp phải. Những người quen của bạn, bạn bè, bà con, cô dì chú bác, bạn của ba của mẹ sẽ gọi điện nhờ bạn giúp khi họ không nghe nhạc được, máy khởi động chậm, không thấy webcam, không biết đưa hình lên blog. Kiểu hỗ trợ kĩ thuật miễn phí này bạn nên cẩn thận vì nó sẽ thường xuyên lặp đi lặp lại. Một số trường hợp bạn sẽ được trả công nhưng theo tôi bạn chẳng cần số tiền chả đáng đổ xăng đó làm gì so với thời gian bạn phải chạy đi chạy lại. Đa số những người nhờ bạn giúp sẽ mong muốn được hỗ trợ miễn phí và tôi chắc chúng ta sẽ không vui gì về điều đó. Vì vậy hãy tập nói không khi có thể.:bbptuc:

5/Bạn sẽ phải thường xuyên về trễ mà không được trả tiền.

- Đặc thù của ngành IT là công việc thường không thể tính chính xác bằng giờ. Có nghĩa là không phải cứ 1 lượng thời gian nào đó thì sẽ làm xong một công việc. Thuờng thì chúng ta sẽ phải ở lại thêm 1h, 2h để làm nốt công việc của mình nếu bạn là người có trách nhiệm. Nhưng dù có trách nhiệm hay không thì khi công việc chưa xong mà đã gần đến deadline thì bạn vẫn phải ở lại để hoàn thành những gì còn dở dang, và tất nhiên không có xu nào cả.:bbpnrang:

6/Bạn sẽ thường xuyên bị stress.

- Khi làm việc với những project lớn nhiều người, công việc sẽ theo flow rõ ràng, bạn làm ngưòi khác test, manager dí, và khi đến những ngày cuối cùng là lúc bạn làm việc nhiều nhất. Phải suy nghĩ nhiều, cơ thể mệt mỏi thiếu ngủ cộng với căng thẳng khi làm việc sẽ khiến nhiều người bị stress. Theo một số điều tra thì thủ phạm gây stress nhiều nhất là email. Khi phải đọc khoảng 100 email một ngày thì người hiền lành cũng trở nên gắt gỏng. Bởi vậy những người làm IT thường hay khó chịu đột xuất.

10 điều tồi tệ khi làm trong ngành CNTT

7/Lương bạn sẽ tăng rất chậm.

- Làm IT lương khởi điểm sẽ khá cao so với một số ngành nhưng tốc độ tăng sẽ chậm và ít đột biến. Thường thì những người làm IT sẽ giải quyết nhu cầu tăng lương bằng cách nhảy sang công ty khác. Cho nên những bạn sinh viên mới ra trường nên tìm một công ty có lương khởi điểm khá tốt vì thông thường chu kì tăng lương sẽ là từng năm và khi lạm phát 2 chữ số mà tăng lương dưới 15% + với trả lương bằng tiền Việt thì hơi bị đuối. Tốt nhất nên tìm hiểu những anh chị đi trước hoặc xác định mục tiêu của mình để tìm hướng đi khác vì làm lập trình chay khó làm giàu lắm.:bbpcuoi3:

8/Không phải lúc nào cũng được làm công việc ưa thích.

- Bạn từng nghĩ sẽ áp dụng những kĩ thuật tiên tiến nhất của các ngôn ngữ lập trình hiện đại, sẽ học hỏi những công nghệ mới nhất và làm việc với những chuyên gia đầy kinh nghiệm trong lĩnh vực CNTT nhưng thường thì không phải như vậy. Ở những công ty càng lớn thì sẽ càng có những project kì lạ kiểu như chuyển nguyên một chương trình từ VB6 sang C#, hoặc từ một ngôn ngữ rất cổ xưa sang C#. Tuy đòi hỏi kiến thức lập trình trên 2 ngôn ngữ, khả năng đọc hiểu code nhưng nói chung công việc như vậy khá nhàm chán và tôi nghĩ chẳng ai muốn theo đuổi lâu dài. Đôí vơí những project lớn thì chi phí cho công nghệ mới là một trong những vấn đề quan tâm của khác hàng. Bạn muốn sử dụng SQL 2005 nhưng khách hàng sẽ nói “No” khi họ đã có licence cho SQL 2000 và không muốn bỏ tiền mua thứ mới. Bạn muốn sử dụng ASP.NET để làm website cho khách hàng nhưng họ cho rằng PHP sẽ rẻ hơn vì không tốn nhiều licence cho máy chủ WINDOWS. Bạn muốn dùng ORM tool để tiết kiệm thời gian lập trình nhưng khách hàng nhất quyết bạn phải dùng Store Procedure và viết code gọi bằng C# vì làm vậy nhanh hơn 30 milisecond khi gọi 10000 query. Nói chung khách hàng là thượng đế và chúng ta phải nghe theo.:bbpcuoi5:

9/Khi nhảy việc cũng không đơn giản, có khi phải bắt đầu lại từ đầu.

- Lương bạn hiện không cao trong khi lương tụi bạn đã gấp 2 mình. Đề nghị xếp tăng lương thì sao, liệu xếp có chịu tăng cho mình gấp rưỡi không chứ đừng nói gấp 2. Tại sao không nhảy việc khi vừa có thể có lương cao hơn lại có thể học hỏi nhiều cái mới và làm quen với nhiều con người mới. Nhưng khi nhảy việc là lúc bạn phải chấp nhận làm lại từ đầu. Có thể bạn có nhiều kinh nghiệm từ công ty cũ nhưng sang môi trường mới sẽ không có đất để dụng võ. Và khi chưa biết gì hết thì bạn sẽ là một newbie và chấp nhận làm lại từ con số không. Vì vậy theo tôi nếu tìm được một công việc mới lương gấp rưỡi trở lên thì hãy nhảy, còn không ở lại cho lành và chờ thời cơ.:bbpraroi:

10 điều tồi tệ khi làm trong ngành CNTT

10/Rất khó để tự kinh doanh riêng về IT

- Tỉ lệ thất bại cao của các công ty IT mới thành lập đã nói lên điều này. Nếu bạn làm IT khi muốn mở một công ty làm phần mềm thì rất khó. Một trong những khó khăn lớn nhất là sự cạnh tranh. Bạn sẽ khó mà kiếm được project từ những khách hàng lớn khi công ty của bạn chưa hề có tên tuổi hoặc không có công ty mẹ đỡ đầu. Nếu chấp nhận làm dự án nhỏ thì có vô khối công ty đã làm như vậy. Những công ty may mắn sống sót nhờ vào dạng những project nhỏ này họ có thể thực hiện website trong vòng một tuần nhờ tái sử dụng những cái đã có từ project cũ và chúng ta sẽ khó mà cạnh tranh nỗi khi kinh nghiệm tổ chức và kinh doành là con số 0. Giỏi lập trình không có nghĩa là giỏi quản lý và càng không có nghĩa là giỏi kinh doanh nên làm công ty về IT không hề đơn giản. Và khi không có một project nào trong khi phải nuôi đội quân cỡ 5 người, cộng với trả tiền điện, tiền mặt bằng trong vòng 3 tháng là bạn phải nghĩ đến chuyện giải tán.:bbpchao:



- Đó là 10 trong khá nhiều những khó khăn, thiệt thòi, gian khổ của ngành IT. Làm IT không đơn giản và không sướng chút nào, càng không dễ làm giàu. Thế nên những ai nghĩ rằng làm IT sướng và lương cao thì nên xem lại và cân nhắc nêú như đang chọn nghề cho mình. Đây là những ý kiến chủ quan của tôi, có thể có nhiều ý kiến trái ngược và bổ sung khác cho nên rất mong được sự chia sẽ từ các bạn. Mọi comment khen ngợi, chửi bới đều hoan nghênh và vui lòng post trực tiếp ở entry này hoặc ở link này. :byebye:

Sử dụng Adapter Pattern Trong Lập Trình Hướng Đối Tượng

Adapter Pattern Samble In Real Life

I/ Giới thiệu.

- Khái niệm Adapter đã xuất hiện từ rất lâu và được sử dụng rất nhiều trong cuộc sống. Thiết bị điện tử của bạn không thể sạc pin bằng điện 220V mà phải thông qua một bộ chuyển, biến điện 220 thành 12V. Bạn có một con chuột với Jack cắm USB nhưng máy đã hết chỗ cắm, người bán tặng bạn thêm 1 bộ chuyển từ USB sang PS2 để giải quyết vấn đề trên…Đó là những ví dụ hay gặp nhất về Adapter, và vì chúng quá thông dụng nên ít ai ngờ đến cái mình đang sử dụng hằng ngày lại là một kiểu adapter nào đó. Từ lâu, khái niệm Adapter đã được 4 đại ca về Design Pattern đưa vào lĩnh vực làm phần mềm và nó tỏ ra có ích không kém. Tôi dám chắc là các bạn ai đều cũng từng sử dụng đến Adapter trong cuộc sống của mình, thế thì tại sao lại không sử dụng nó trong lập trình để giải quyết những vấn đề tương tự:bbpskien: :

Adapter Pattern Samble In Real Life
Adapter Pattern Samble In Real Life

Adapter Pattern Samble In Real Life
Adapter Pattern Samble In Real Life


- Inheritance là một trong 3 nguyên tắc cơ bản của lập trình hướng đối tượng. Khi cần xây dựng một lớp dựa trên một hoặc nhiều lớp hay interface có sẵn bạn chỉ cần khai báo lớp mới kế thừa lớp cũ và có thể viết thêm những method, attribute của mình tùy thích. Tuy nhiên sẽ có lúc tính kế thừa của OOP sẽ không sử dụng được. Thật sự là có nhiều trường hợp như vậy mà tôi đã từng gặp phải. Giả sử bạn cần mở rộng một lớp nhưng lớp đó là lớp seal (không cho kế thừa) thì inheritance chắc chắn không sử dụng được rồi. Một ví dụ khác là khi bạn cần kết hợp nhiều thứ có sẵn để làm ra một lớp mới sử dụng lại những thứ đó. Như các bạn biết C# và Java không hỗ trợ đa kế thừa, chúng ta không thể nào kế thừa từ 2 lớp có sẵn được. Như vậy nếu bạn đã có một lớp để tìm ước số chung lớn nhất của hai số tự nhiên, một lớp để cộng hai phân số, và khi dùng adapter để kết hợp hai thứ có sẵn đó bạn sẽ làm được một lớp có khả năng cộng hai phân số với nhau với kết quả phép cộng là phân số đã tối giản.:bbpnen:

- Như vậy, Adapter Pattern là một design pattern, nó còn được gọi là Wrapper Pattern biến đổi một lớp không thể sử dụng trực tiếp được thành một lớp mới có thể sử dụng. Trong một số trường hợp, Adapter Pattern còn được sử dụng để biến đổi dạng dữ liệu. Để tiết kiệm chỗ trong và giảm tính phức tạp trong database, nhiều giá trị string có thể được lưu thành một string duy nhất với kí tự phân cách đặc biệt, mẫu Adapter sẽ chịu trách nhiệm tách các string đó ra thành array để nơi khác có thể sử dụng. Nhưng nói chung Adapter Pattern được sử dụng đúng nhất khi biến cái không thể thành cái có thể.:bbpraroi:

II/ Sử dụng Adapter Pattern như thế nào?

- Theo tôi nói ở trên, Adapter Pattern thường được dùng để biến cái không thể thành cái có thể, biến lớp không thể sử dụng thành một lớp mới có thể sử dụng. Tuy nhiên, Adapter Pattern còn được dùng để biến những lớp có sẵn thành một thứ khác dễ và tiện sử dụng hơn. Vì vậy có hai cách thiết kế và áp dụng Adapter Pattern trong lập trình, ở một số tài liệu Design Pattern, hai cách này được gọi là Object Adapter Pattern Class Adapter Pattern. Một số trang còn gọi là Inheritance-Way Composition-Way. Nói chung những cách gọi này đều dựa trên cách thiết kế lớp Adapter. Object Adapter Pattern hay Composition-Way là cách sử dụng một đối tượng thuộc về lớp chúng ta muốn biến đổi bên trong lớp Adapter. Trong khi đó, ClassAdapterPattern hay Inheritance-Way là cách kế thừa từ lớp chúng ta muốn biến đổi hoặc mở rộng thêm.

III/ Ví dụ mẫu về Adapter Pattern

- Tôi sẽ lần lượt đưa 2 ví dụ thiết kế lớp về 2 cách này:

A. Object Adapter Pattern (Composition-Way)

- Để kiếm đủ tiền ăn nhậu, massage:bbpxtay:, ngoài giờ làm ở cty tôi nhận làm thêm một ứng dụng quản lý bán hàng, trong đó có hỗ trợ lập biểu đồ thể hiện doanh số các kiểu. Hiện tại tôi đã đạo được phần code vẽ biểu đồ cột của một tên sinh viên học cùng trường. Tiếc thay search mãi thì chỉ tìm được một thư viện vẽ biểu đồ tròn nhưng không có source code: CloseSourceCode.BarChart. Tuy có thói quen đạo code thiên hạ:bbpcuoi3:, nhưng chương trình của tôi đã thiết kế với tính loose coupling rất cao nên đã sửa lại code của tên sinh viên đó, và truy xuất lớp đó qua Interface: IMyChart. Như vậy với cách làm thông thường tôi không thể sử dụng lớp CloseSourceCode.BarChart được vì CloseSourceCode.BarChart không thuộc interface IMyChart. Nhờ tìm hiểu kĩ về Adapter Pattern, tôi biết rằng có thể áp dụng Object Adapter Pattern trong trường hợp này. Tôi sẽ làm một lớp ThoaiChart (Thoại là tên tôi) implement từ interface IMyChart, và bên trong ThoaiChart tôi sẽ sử dụng lớp CloseSourceCode.BarChart để vẽ. Thiết kế lớp như sau:

Object Adapter Pattern

B. Class Adapter Pattern (Inheritance-Way)

- Tôi đã rất mừng khi phát hiện ra rằng chỉ mất chút ít thời gian để làm cái BarChart. Nhưng khi đưa cho khách hàng, họ yêu cầu tôi phải sửa lại cái BarChart, phải cho người dùng thấy được số liệu khi rê chuột lên hình. Đúng là đồ free có khác, không khi nào dùng ngay được. Tôi đành phải thiết kế lại lớp ThoaiChart theo hướng khác. Bây giờ tôi sẽ inherit lớp CloseSourceCode.BarChart và override lại hàm hover chuột của nó. Thiết kế lớp như sau:

Class Adapter Pattern


IV/ So sánh Adapter Pattern với các Design Patterns khác?

- Trong các Design Pattern thuộc nhóm Structural Design Pattern, có rất nhiều mẫu có thiết kế lớp tương tự nhau. Chúng ta nên nắm rõ ý nghĩa và trường hợp sử dụng của chúng để không nhầm lẫn và … để khi em trai em gái nó hỏi còn biết đường trả lời :bbpbuon:. Trong phần so sánh giữa Adapter Pattern với các Design Patterns khác, tôi có nhắc nhiều đến từ interface của lớp (class). Bạn hãy hiểu đó như là kiểu(type) của lớp. Các lớp khác namespace và khác base class (base type) sẽ có interface khác nhau. Một số tác giả Việt Nam dịch interface của lớp là "giao diện của lớp", riêng cá nhân tôi thì thấy dịch như vậy cũng kì. Một điểm nữa là các bạn cần phân biệt interface trong trường hợp này với interface trong chữ GUI, và càng nên phân biệt nó với khái niệm interface trong một số ngôn ngữ lập trình như C#, Java, ...

• Với khả năng biến cái không thể thành có thể, Adapter Pattern làm cho 1 lớp có thể sử dụng được sau khi lớp đó đã được thiết kế xong trong khi Bridge Pattern làm điều đó trước khi lớp này được tạo ra.
Bridge Pattern được nghĩ ra với ý tưởng tách rời những abstraction ra khỏi những implementation, và tạo tính độc lập cao giữa chúng. Trong khi đó, Adapter pattern đươc dùng để làm những lớp không liên quan (không cùng namespace, khác interface) có thể làm việc với nhau.
• Adapter Pattern về ý nghĩa sẽ biến đổi interface của một lớp, Proxy Pattern sẽ không đổi interface của một lớp và Decorator Pattern sẽ kế thừa và mở rộng dựa trên interface đó.
• Adapter Pattern khi dùng sẽ thay đổi interface của một đối tượng có sẵn để biến nó thành thứ có thể dùng được. Decorator Pattern sẽ phát triển thêm trên một đối tượng mà không làm thay đổi interface của nó
• Giống với Adapter Pattern, Façade Pattern có thể kết hợp nhiều xử lý vào một lớp mới đơn giản và gọn hơn , nhưng nó sẽ định nghĩa mới 1 interface trong khi Adapter Pattern tái sử dụng một interface (Trong ví dụ về các biểu đồ ở trên thì interface được tái sử dụng là IMyChart, không hề có một interface mới được tạo ra)


- Các bạn có thể tham khảo thêm những ví dụ code mẫu cho Adapter Pattern ở trang wiki. Ví dụ thứ hai ở trang này là biến đổi 1 lớp DList thành Stack dựa trên những xử lý có sẵn của DList mà không cần viết lại những xử lý phức tạp cho lớp Stack.

Tài liệu tham khảo:

rss
 

About Me

Place I've live
Near Bossley Park, Sydney, NSW, Australia
Place I've work
  • Freelancer (from 06/2010 to present)
  • Harvey Nash (from 05/2008 to 06/2010)
  • DataDesign Vietnam (10/2005 to 04/2008)
Place I've studied
  • University of Natural Science (Bachelor of Science HoChiMinh City Vietnam From 2001 to 2005)
  • Le Hong Phong High School (HoChiMinh City Vietnam From 1997 to 2000)