Console MVC Library cho .NET (1): giới thiệu chung

Giới thiệu chung về console, ứng dụng enterprise, mvc, framework

0

Đây là loạt bài hướng dẫn cách xây dựng một MVC framework đơn giản nhưng hữu ích cho ứng dụng console.

Loạt bài Xây dựng thư viện hỗ trợ ứng dụng Console:
Phần 1 – Giới thiệu chung
Phần 2 – Truy vấn, xây dựng router
Phần 3 – Hỗ trợ I/O với console, view, controller
Phần 4 – Ví dụ minh họa

Mô hình MVC đã quá quen thuộc với người học và làm về mảng lập trình ứng dụng. Các nền tảng hỗ trợ phát triển ứng dụng web đều xây dựng sẵn các framework rất mạnh cho mô hình MVC. Như vậy chẳng có lý do gì để đi xây dựng một framework MVC nữa.

Nhưng khoan! Ở đây chúng ta đang nói tới ứng dụng console (ứng dụng có giao diện dòng lệnh). Tại sao lại là ứng dụng console? Lập trình ứng dụng console nên sử dụng mẫu kiến trúc giao diện (architechtural pattern) nào? Có MVC framework nào dành cho ứng dụng console không?

Tại sao là ứng dụng console?

Ứng dụng console với giao diện dòng lệnh đen xì chắc là một nỗi ám ảnh với người bắt đầu học lập trình. Trong các trường đại học, các khóa học từ nhập môn lập trình cho tới lập trình hướng đối tượng hay trúc dữ liệu và thuật toán đều chỉ thực hiện ví dụ trên giao diện này. Mọi tài liệu dạy lập trình đều bắt đầu bằng chương trình Hello world trên màn hình đen xì đó. Chỉ khi nào học hành “thành tài” mới thoát được loại ứng dụng này.

Nhưng, đừng coi thường ứng dụng console.

Ứng dụng console là loại ứng dụng có giao diện đơn giản nhất, giúp người mới học lập trình tránh xa những sự phức tạp (chưa cần thiết) của các công nghệ GUI (giao diện đồ họa).

Ứng dụng console sử dụng nhiều cho mục đích tính toán và xử lý, thay vì thể hiện dữ liệu. Nhiều chương trình tính toán nặng (trong khoa học) hay được viết bằng console thay vì dùng GUI. Các chương trình server thì hoàn toàn không cần đến GUI.

Ứng dụng console có hiệu suất cao và an toàn. Trên thực tế, rất nhiều ứng dụng dành cho quản trị hệ thống đều sử dụng giao diện console. Chắc ai cũng biết Ping, IpConfig, Tracert trên windows. Windows server còn có hẳn một giao diện dòng lệnh cao cấp (power shell) với hầu hết các công cụ đều thực hiện ở giao diện dòng lệnh. Nếu làm việc với Linux thì … thôi rồi, toàn chương trình console chạy trên shell.

Windows ping
Ví dụ chương trình Ping của windows

Ứng dụng console không phụ thuộc quá chặt chẽ vào shell đồ họa của hệ thống và dễ dàng phục vụ đa nền tảng. Ví dụ, một ứng dụng console viết trên .NET framework (cho windows) có thể dễ dàng chạy tiếp trên Linux (Mono). Nếu từng nghịch một số private server của game (như Aion), có thể thấy bản thân server này là một ứng dụng console viết bằng Java. Có thể chạy server này trên Linux hoặc Windows.

Nói túm lại, không được coi thường ứng dụng console.

Có những vấn đề gì khi lập trình ứng dụng console?

Vấn đề hiển nhiên nhất với ứng dụng console là việc xuất nhập dữ liệu. Mọi thứ xuất ra console đều là văn bản. Mọi thứ đọc vào từ console cũng đều là văn bản. Từ đây dẫn đến yêu cầu phải chuyển đổi kiểu dữ liệu khi xuất/nhập dữ liệu.

Vấn đề thứ hai là nhận lệnh và quyết định phương thức tương ứng nào sẽ được thực thi. Đối với các chương trình mini trong khuôn khổ “nhập môn lập trình” thì đây không phải là vấn đề. Người mới học dễ dàng nghĩ tới sử dụng các cấu trúc rẽ nhánh để chọn phương thức phù hợp. Vậy nếu như có vài chục lệnh hoặc nhiều hơn nữa? Bao nhiêu cấu trúc if hoặc bao nhiêu nhánh case (của switch) sẽ phải sử dụng?

Vấn đề thứ ba là tham số đi kèm mỗi lệnh. Một lệnh người dùng nhập không thể thiếu tham số. Ví dụ, tôi cần xóa file “xyz.com”. Vậy “xyz.com” là tham số đi cùng lệnh. Làm thế nào để dễ dàng tiếp nhận, chuyển đổi và sử dụng tham số đó với lệnh? Tôi tin rằng, đây là một vấn đề rất lớn với người lập trình với giao diện console.

Vấn đề tiếp nữa là giao diện cho từng lệnh. Nghe đơn giản? Chưa chắc đâu. Giả sử, người dùng cần xóa một file. Bạn phải làm gì? Hỏi xem người dùng có chắc chắn xóa file không. Nếu có, sau khi xóa file sẽ phải thông báo hoặc thành công hoặc thất bại. Nếu người dùng đổi ý sẽ phải thông báo hủy lệnh xóa. Như vậy, một chức năng đơn giản đã phải có ít nhất ba loại giao diện khác nhau tùy từng tình huống.

Ngoài các vấn đề chính trên, còn những thứ khác phải lăn tăn khi xây dựng ứng dụng console. Cụ thể là: làm việc với dữ liệu (lưu trữ/truy vấn) ở đâu, như thế nào? Có thể thay đổi dễ dàng cơ chế quản lý dữ liệu không? Khi ứng dụng cần mở rộng sẽ làm như thế nào? Khi cần phát triển theo nhóm (nhiều người làm cùng lúc) thì sao? Những câu hỏi này không chỉ áp dụng với ứng dụng console mà còn đúng với ứng dụng bất kỳ.

Như vậy chúng ta có thể thấy, ứng dụng console hoàn toàn không phải đơn giản và nhàm chán như chúng ta tưởng tượng. Để phát triển một ứng dụng console “đàng hoàng” phải thực hiện rất nhiều kỹ thuật và nguyên lý lập trình cao cấp. Đây chính là mục đích của chúng ta trong loạt post này.

Các vấn đề của lập trình ứng dụng Enterprise

Việc phát triển một ứng dụng nói chung thường phải đáp ứng các yêu cầu: dễ dàng thay đổi các thành phần khi cần thiết (ví dụ, cơ chế lưu trữ dữ liệu), đáp ứng khả năng mở rộng, dễ dàng bảo trì, đơn giản trong hoạt động nhóm. Để đảm bảo các yêu cầu đó, đối với lập trình hướng đối tượng, người ta đưa ra một số nguyên lý chung:

Bộ nguyên lý SOID. Đây là một nhóm nguyên lý dựa trên những kinh nghiệm tốt nhất về lập trình hướng đối tượng. Bất kỳ ai khi hiểu những nguyên lý cơ bản của lập trình hướng đối tượng đều phải học để bắt tay vào làm thực tế. Hãy tự tìm hiểu bộ nguyên lý này và cách thức vận dụng của nó trong từng công nghệ khác nhau.

Mô hình phát triển ứng dụng DDD (Domain-Driven Design). Đây là mô hình được sử dụng rất nhiều trong phát triển ứng dụng Enterprise, đặc biệt là ứng dụng LOB (Line-of-Business, ứng dụng quản lý). Mô hình này đem đến những khái niệm được sử dụng rất phổ biến trong phát triển ứng dụng: Entity (thực thể), Value object (đối tượng mang giá trị), Aggregate (tập hợp giá trị), Repository (quản lý truy xuất và lưu trữ dữ liệu tập trung).

Quan hệ mềm giữa các class (loosely coupling). Tạo ra quan hệ lỏng lẻo giữa các class sao cho có thể dễ dàng thay thế class này bằng class khác trong quá trình phát triển hoặc hoạt động của ứng dụng. Quan hệ này kết hợp với nguyên lý D (Dependency Inversion) của bộ nguyên lý SOLID tạo ra một hệ thống rất uyển chuyển để có thể dễ dàng thay thế các thành phần của một ứng dụng mà không ảnh hưởng đến các thành phần còn lại.

Các mẫu kiến trúc (architectural pattern) như MVC, MVP, MVVM. Đây là các nguyên tắc chung về cách thức tổ chức code của class và cách thức tương tác giữa các class để tạo ra thành phần giao diện của một ứng dụng. Mỗi mẫu kiến trúc thường phù hợp với một (số) loại công nghệ nhất định. Ví dụ, MVC được xem là đặc biệt phù hợp với ứng dụng web (cả hệ thống, hoặc riêng client), MVVM được xây dựng riêng cho công nghệ WPF của Microsoft, MVP áp dụng rất tốt với công nghệ Windows forms.

Các mẫu thiết kế (design pattern) như singleton, mediator, proxy. Đây là loại giải pháp cho những vấn đề thường gặp trong lập trình hướng đối tượng. Ví dụ, mẫu thiết kế singleton giúp giải quyết vấn đề tạo ra một object duy nhất của class trong toàn bộ ứng dụng và cách truy cập object này. Mẫu thiết kế này được vận dụng rất nhiều để tạo ra hệ thống cấu hình hoặc lưu vết (log) hoạt động của ứng dụng.

Mô hình MVC

Đây là một mẫu kiến trúc (architechtural pattern) ra đời sớm nhất. MVC không được quá “trọng dụng” cho đến thời kỳ ứng dụng web “lên ngôi”. Hiện nay, MVC là mẫu kiến trúc phổ biến nhất (nếu không muốn nói là độc tôn) trong phát triển ứng dụng web.

Mô hình này dựa trên việc phân chia code của ứng dụng (nói chung, về thành phần giao diện) thành ba phần: Model, View, Controller. Model là nơi lưu trữ dữ liệu; View là nơi hiển thị dữ liệu của Model; Controller tiếp nhận yêu cầu từ client, ghép nối Model với View, thực hiện các xử lý cần thiết.

Điểm đặc thù của MVC ở chỗ, Model là thành phần độc lập nhất, luôn được xây dựng đầu tiên trong ứng dụng và chi phối hầu hết các thành phần khác. View được xây dựng tiếp theo nhằm hiển thị thông tin của Model cho người dùng. Controller xây dựng sau cùng để xử lý yêu cầu của người dùng và ghép nối View với Model. Trong hệ thống đó, Model không biết đến View, View không biết đến Controller.

Tương tác giữa các thành phần trong mô hình MVC
Tương tác giữa các thành phần trong mô hình MVC

Để đảm bảo hoạt động theo mô hình như vậy, trong mô hình MVC thường phải xây dựng thêm một thành phần gọi là Router để đảm bảo trao đổi thông tin từ View đến Controller, cũng như đảm bảo việc tiếp nhận truy vấn từ người dùng của Controller.

Trong mô hình này hoàn toàn có thể áp dụng đầy đủ các nguyên lý SOLID, mẫu Repository (cho quản lý dữ liệu), các mẫu thiết kế (ví dụ, singleton hoặc mediator cho Router), sử dụng kỹ thuật tạo loosely-coupling cho Repository (để dễ dàng thay đổi thành phần truy xuất dữ liệu).

Các yêu cầu chính của framework

Trong các bài tiếp theo của loạt bài này chúng ta sẽ đi vào phân tích chi tiết từng vấn đề:

  • Thứ nhất, framework cần xây dựng một cơ chế gọi tên là router để ánh xạ truy vấn của người dùng sang thực thi một phương thức cụ thể.
  • Thứ hai, framework cần xây dựng các lớp view cơ sở, giúp người sử dụng framework tạo ra các lớp view cụ thể theo nhu cầu.
  • Thứ ba, framework cần xây dựng một lớp controller cơ sở để người lập trình tự tạo ra lớp controller riêng một cách đơn giản.
  • Ngoài ra, framework cũng có một số class hỗ trợ cho việc đưa ra các thông báo ngắn, thay cho việc xây dựng rất nhiều lớp view nhỏ.

Mã nguồn solution cung cấp ở bài cuối cùng của chuỗi.


Loạt bài Xây dựng thư viện hỗ trợ ứng dụng Console:
Phần 1 – Giới thiệu chung
Phần 2 – Truy vấn, xây dựng router
Phần 3 – Hỗ trợ I/O với console, view, controller
Phần 4 – Ví dụ minh họa

Theo dõi
Thông báo của
guest

0 Thảo luận
Phản hồi nội tuyến
Xem tất cả bình luận