Tôn vinh Nhã nhạc tại Festival Huế 2012
Tại Festival Huế 2012, Nhã nhạc Huế tiếp tục được tôn vinh qua lễ hội “Ngự thuyền khám phá sông Hương” và “Đêm Hoàng Cung” nhằm đưa bộ môn nghệ thuật chỉ phục vụ trong cung vua xưa đến rộng rãi với công chúng. Các hoạt động của “Đêm Hoàng Cung” sẽ được bố trí trên 3 trục chính: trục giữa (từ Ngọ Môn đến nền điện Kiến Trung), trục trái (từ Thế Miếu đến cung Trường Sanh) và trục phải (từ phủ Nội Vụ đến vườn Cơ Hạ), với các trò chơi cung đình, chương trình Dạ nhạc tiệc cung đình, Đêm Phương Đông, và các vũ khúc cung đình…
![]() |
| Biểu diễn nhã nhạc tại Festival Huế |
Ông Phan Thanh Hải, Phó Giám đốc phụ trách Trung tâm Bảo tồn di tích Cố đô Huế cho biết: Từ năm 2003, khi Nhã nhạc cung đình Huế (Âm nhạc cung đình Việt Nam) được UNESCO tôn vinh là Di sản văn hoá phi vật thể và truyền khẩu của nhân loại đến nay, Trung tâm đã sưu tầm, bảo tồn và dàn dựng được hơn 30 nhạc chương trong các lễ tế, 40 nhạc khúc được diễn tấu với nhiều loại tiểu nhạc, đại nhạc, gần 20 điệu múa cung đình đã được phục hồi, dựng được 3 vở tuồng cổ đáp ứng cho các lễ hội và giao lưu văn hoá. Trung tâm tổ chức tốt công tác truyền nghề từ các nghệ nhân nhã nhạc Huế còn lại trên đất Cố đô, Thừa Thiên – Huế; tổ chức 4 lớp đào tạo diễn viên với nhiều chương trình như Nhã nhạc, tuồng và múa cung đình…bổ sung cho Nhà hát Nghệ thuật truyền thống Cung đình Huế.
Bên cạnh đó, Trung tâm cũng tiến hành nhiều cuộc điền dã ở thành phố Huế và các vùng phụ cận, gặp gỡ, tiếp xúc và trò chuyện với nhiều nghệ nhân, nghệ sĩ, những người vốn trước đây đã có thời gian phục vụ và làm việc trong cung dưới thời các vua cuối cùng của triều Nguyễn. Nhiều tư liệu quý về các loại hình Nhã nhạc, tuồng và múa cung đình đã được thu thập, trên cơ sở đó nhóm nghiên cứu đã tập hợp, phân loại và xây dựng thành bộ hồ sơ khoa học. Đến thời điểm hiện tại, bộ hồ sơ khoa học này đã thu được 250 trang viết, giới thiệu về sự nghiệp của nghệ nhân, nghệ sĩ và ký âm các bài bản do họ thể hiện, 22 băng ghi âm, 45 đĩa DVD với nội dung ghi lại các kỹ thuật trình tấu, kỹ năng nghề nghiệp của nghệ nhân, nghệ sĩ thuộc bộ môn Nhã nhạc cung đình Huế.
Tỉnh Thừa Thiên – Huế đang tập trung thực hiện 10 biện pháp trước mắt để bảo tồn Nhã nhạc cung đình Huế (Âm nhạc cung đình Việt Nam) đó là: nghiên cứu xây dựng Trung tâm nghiên cứu Văn hoá phi vật thể vùng Huế; củng cố và phát triển về cơ sở vật chất và diễn viên cho Nhà hát Nghệ thuật truyền thống Cung đình Huế để thành trung tâm của các chương trình biểu diễn nghệ thuật truyền thống Cung đình ở Việt Nam; tiến tới tổ chức định kỳ các chương trình biểu diễn giao lưu nghệ thuật quốc tế giữa Nhã nhạc Cung đình Huế với các nghệ thuật biểu diễn Cung đình của một số nước trong khu vực như Hàn Quốc, Nhật Bản.
Trước mắt, tỉnh Thừa Thiên – Huế tiếp tục cập nhật và bổ sung thông tin, dữ liệu về các nghệ nhân, các nhân chứng của Nhã nhạc; thực hiện các đề tài nghiên cứu khoa học về giá trị lịch sử và nghệ thuật, các hình thức diễn tấu, các bài bản hiện còn và đang bị thất lạc; mở rộng nghiên cứu về các lễ hội cung đình của triều Nguyễn; tiếp tục mở rộng quan hệ hợp tác trong nghiên cứu tư liệu và công nghệ chế tác nhạc cụ truyền thống; quảng bá và cung cấp thông tin cho cộng đồng; chuẩn hoá về chương trình biểu diễn Nhã nhạc và múa cung đình, về trang phục và phong cách biểu diễn…
Theo Baotintuc.vn
Giới thiệu thư viện MvpPattern dùng xây dựng mô hình ứng dụng dựa trên kiến trúc MVP
bởi Nguyễn Thành Mãn vào 8 tháng 1 2013 lúc 17:20 ·
Giới thiệu thư viện MvpPattern dùng để xây dựng mô hình ứng dụng dựa trên kiến trúc Model – View – Presenter
1 Giới thiệu
Trong quá trình thực hiện dự án Phần mềm quản lý tư liệu và Website Nhã nhạc cung đình Huế, từ kinh nghiệm của các dự án trước và qua tìm hiểu tham khảo trên Internet, nhóm thực hiện dự án đã học hỏi, cải tiến và tổ chức lại thành thư viện MvpPattern chạy trên nền tảng .NET, với mục tiêu nâng cao tính tái sử dụng, giảm bớt khối lượng mã cần viết cho các thao tác thường gặp khi xây dựng phần mềm áp dụng theo mô hình Model-View-Presenter (MVP). Mô hình MVP đã khá quen thuộc với giới lập trình nên việc giới thiệu nằm ngoài phạm vi bài viết này. Đây là phiên bản đầu tiên, bước đầu chỉ mới khái quát hóa vấn đề ở mức độ cơ bản, nên có một số điểm vẫn chưa được hoàn thiện, chưa được như mong muốn. Trong quá trình ứng dụng thực tiễn, thư viện sẽ tiếp tục được cải tiến cho phù hợp và tiện lợi hơn. Chúng tôi chia sẻ một số kinh nghiệm và mong nhận được ý kiến đóng góp.
Các ví dụ sử dụng theo cách lập trình truyền thống, chưa đáp ứng hoàn toàn nguyên lý đảo ngược phụ thuộc (Dependency Inversion Principle – DIP[*], cách gọi khác là Inversion of Control – IoC), việc áp dụng nguyên lý này làm giảm bớt sự kết nối (decoupling) chặt chẽ giữa các đối tượng trong phần mềm, tăng độ linh hoạt và giúp phần mềm có tính module hóa cao. Trong khuôn khổ bài viết không thể trình bày đầy đủ, xin tham khảo mã nguồn ví dụ áp dụng thư viện Unity Application Block (phiên bản 2.1) để cài đặt mẫu thiết kế (design pattern) dependency injection.
2 Cấu trúc gói
2.1 Biểu đồ gói
Các giao diện và lớp của thư viện.

Vị trí của thư viện trong mô hình MVP.

Ghi chú: Các giao diện và lớp có màu đen là mã ví dụ, không thuộc thành phần của thư viện.
2.2 Tổng quan
Áp dụng thư viện MvpPattern cho phát triển mô hình phần mềm dựa theo kiến trúc ba tầng Model – View – Presenter(MVP). MvpPattern theo cơ chế Passive View, tất cả các tương tác từ tầng giao diện (View) đi xuống và tầng dữ liệu (Model) trở lên đều thông qua tầng trung gian nghiệp vụ (Presenter).
Tầng dữ liệu sử dụng LINQ (LINQ được Microsoft tích hợp vào Visual Studio từ phiên bản 2008. tuy nhiên vẫn có thể dùng trong phiên bản 2005, lưu ý là LINQ chỉ dùng được cho hệ quản trị cơ sở dữ liệu MS SQL Server) và kết hợp với thư viện Dynamic LINQ để tạo các câu truy vấn có điều kiện tương tự câu lệnh truy vấn SQL quen thuộc.
2.2.1 Tầng Business
2.2.1.1 Giao diện IGenericView
Giao diện gốc, với mục đích cho các giao diện khác kế thừa.
public interface IGenericView
{
}
2.2.1.2 Giao diện IListManipulationView
Định nghĩa các thuộc tính và sự kiện thao tác cơ bản là thêm mới, chỉnh sửa, xóa bỏ và lựa chọn khi xử lý dữ liệu trên một danh sách, dẫn xuất từ IGenericView.
public interface IListManipulationView : IGenericView
{
// Trả về hoặc thiết lập danh sách các đối tượng của view
IList ListItem { set; get; }
// Trả về đối tượng được tạo mới trên view
TEntity NewItem { get; }
// Trả về đối tượng hiện hành trên danh sách của view
TEntity CurrentItem { get; }
// Trả về danh sách các đối tượng được lựa chọn trên view
IList SelectedItems { get; }
// Sự kiện phát sinh khi thêm một hạng mục dữ liệu mới
event EventHandler OnAddEventHandler;
// Sự kiện phát sinh khi lưu trữ thông tin của hạng mục dữ liệu
event EventHandler OnSaveEventHandler;
// Sự kiện phát sinh khi xóa bỏ các hạng mục dữ liệu
event EventHandler OnDeleteEventHandler;
// Sự kiện phát sinh khi các hạng mục dữ liệu được lựa chọn
event EventHandler OnSelectEventHandler;
}
Ví dụ: Form danh sách người dùng có các thao tác thêm mới, cập nhật và xóa bỏ. Định nghĩa giao diện IUserView kế thừa từ giao diện IListManipulationView, định nghĩa thêm một số thuộc tính cần thiết khác và thi hành giao diện này cho form.
public interface IUserView : IListManipulationView
Thi hành giao diện mới cho form:
public partial class frmUser : Form, IUserView
2.2.1.3 Giao diện IListSelectionView
Định nghĩa các thuộc tính và sự kiện khi lựa chọn các hạng mục dữ liệu trên một danh sách, dẫn xuất từ IGenericView.
public interface IListSelectionView : IGenericView
{
// Trả về hoặc thiết lập danh sách các đối tượng của view
IList ListItem { set; get; }
// Trả về danh sách các đối tượng được lựa chọn trên view
IList SelectedItems { get; }
// Sự kiện phát sinh khi các hạng mục dữ liệu được lựa chọn
event EventHandler OnSelectEventHandler;
}
Người phát triển có thể định nghĩa ra các giao diện mới tùy theo nhu cầu hoặc kế thừa từ các giao diện trên.
Ví dụ: Có một form danh sách người dùng và sử dụng để lựa chọn ra một số người dùng từ danh sách đó, ta định nghĩa giao diện IUserSelectionView kế thừa từ giao diện IListSelectionView, định nghĩa thêm một số thuộc tính cần thiết khác và thi hành giao diện này cho form.
public interface IUserSelectionView : IListSelectionView
Thi hành giao diện cho form:
public partial class dlgUser : Form, IUserSelectionView
2.2.1.4 Lớp tổng quát GenericPresenter
Lớp chứa các phương thức phổ biến khi thực hiện các thao tác xử lý trên danh sách. Người phát triển có thể override các phương thức này tùy theo nhu cầu sử dụng.
Ví dụ tạo presenter kế thừa từ GenericPresenter, mỗi presenter gắn với view mà nó điều khiển:
public class UserPresenter : GenericPresenter
Khởi tạo đối tượng UserPresenter từ view như sau:
public partial class frmUser : Form, IUserView
{
private UserPresenter presenter;
private void frmUser_Load(object sender, EventArgs e)
{
// Khởi tạo đối tượng presenter
presenter = new UserPresenter();
// Gắn tham chiếu của form thực thi giao diện cho presenter
presenter.View = this;
2.2.1.4.1 Thuộc tính View
Mô tả: Trả về hoặc thiết lập tham chiếu đến view gắn với presenter. Thao tác gán giá trị cho thuộc tính View gọi phương thức OnViewSet.
Cú pháp:
TView View { get; set; }
Ví dụ: Thiết lập giá trị View cho presenter.
presenter = new UserSelectionPresenter();
presenter.View = this;
2.2.1.4.2 Phương thức OnViewSet
Mô tả: Phương thức được gọi khi thuộc tính view của presenter được gán giá trị (xem 2.2.1.4.1).
Cú pháp: public abstract void OnViewSet();
Ví dụ:
public override void OnViewSet()
{
// Khởi tạo dịch vụ xử lý dữ liệu
service = UserGroupService.Instance;
// Đăng ký hàm nhận thông báo mỗi khi dữ liệu có sự thay đổi
service.DataChanged += new DataChangeHandler(FillData);
// Đăng ký các hàm xử lý sự kiện
RegisterEvents();
// Điền thông tin vào giao diện trong lần đầu chạy ứng dụng
FillData();
}
2.2.1.4.3 Phương thức RegisterEvents
Mô tả: Đăng ký các phương thức xử lý sự kiện xảy ra trên view. Có sẵn bốn sự kiện thường gặp là tạo mới, chỉnh sửa, xóa bỏ và lựa chọn hạng mục dữ liệu, thông thường với view dẫn xuất từ IListManipulationView thì sử dụng cả bốn sự kiện trên, còn view dẫn xuất từ IListSelectiontionView thì chỉ đăng ký sự kiện OnSelectEventHandler.
Cú pháp: public virtual void RegisterEvents();
Ví dụ:
public override void RegisterEvents()
{
View.OnAddEventHandler += new EventHandler(OnAddEventHandler);
View.OnSaveEventHandler += new EventHandler(OnSaveEventHandler);
View.OnDeleteEventHandler += new EventHandler(OnDeleteEventHandler);
View.OnSelectEventHandler += new EventHandler(OnSelectEventHandler);
}
2.2.1.4.4 Phương thức OnAddEventHandler
Mô tả: Xử lý sự kiện tạo hạng mục dữ liệu mới trên view.
Cú pháp: public virtual void OnAddEventHandler;
Ví dụ:
public override void OnAddEventHandler(object sender, EventArgs e)
{
userService.Insert(View.NewItem);
}
2.2.1.4.5 Phương thức OnSaveEventHandler
Mô tả: Xử lý sự kiện lưu thông tin hạng mục trên view.
Cú pháp: public virtual void OnSaveEventHandler;
Ví dụ:
public override void OnSaveEventHandler(object sender, EventArgs e)
{
userService.Update(View.CurrentItem, “UserID=” + View.CurrentItem.UserID);
}
2.2.1.4.6 Phương thức OnDeleteEventHandler
Mô tả: Xử lý sự kiện xóa bỏ hạng mục dữ liệu trên view.
Cú pháp: public virtual void OnDeleteEventHandler;
Ví dụ:
public override void OnDeleteEventHandler(object sender, EventArgs e)
{
userService.Delete(View.SelectedItems);
}
2.2.1.4.7 Phương thức OnSelectEventHandler
Mô tả: Xử lý sự kiện lựa chọn hạng mục dữ liệu trên view
Cú pháp: public virtual void OnSelectEventHandler;
Ví dụ:
public override void OnSelectEventHandler(object sender, EventArgs e)
{
userService.AddToGroup(View.CurrentGroup, View.SelectedItems);
}
2.2.2 Tầng Data
2.2.2.1 Giao diện IGenericService
Giao diện gốc, với mục đích cho các giao diện khác dẫn xuất.
public interface IGenericService
{
}
2.2.2.2 Giao diện IGenericDataAccessService
Định nghĩa các phương thức xử lý dữ liệu thông dụng, dẫn xuất từ IGenericService. Gồm các phương thức cơ bản như truy vấn, các thao tác thêm mới, cập nhật, xóa bỏ đối tượng và gửi thông báo mỗi khi dữ liệu có sự thay đổi.
2.2.2.3 Lớp tổng quát GenericDataAccessService
Lớp tổng quát này thi hành từ giao diện IGenericDataAccessService.
2.2.2.3.1 Phương thức khởi tạo đối tượng GenericDataAccessService
Mô tả: Phương thức khởi tạo đối tượng (constructor).
Cú pháp: GenericDataAccessService(System.Data.Linq.DataContext dataContext)
Tham số: Đối tượng Linq.LINQ.DataContext. Thông báo biệt lệ ArgumentNullException nếu tham số bằng Null. Tham số của đối tượng LINQ.DataContext là chuỗi kết nối tới cơ sở dữ liệu.
Trả về: Đối tượng GenericDataAccessService
Ví dụ:
public class UserService : GenericDataAccessService, IUserService
{
// Constructor (strConnectionString là chuỗi kết nối tới cơ sở dữ liệu)
public UserService() : base(new MvpExampleDataContext(strConnectionString)) { }
2.2.2.3.2 Thuộc tính DataContext
Mô tả: Trả về tham chiếu DataContext của đối tượng GenericDataAccessService.
Trả về: Đối tượng LINQ.DataContext
Ví dụ:
// Viết ra chuỗi kết nối đến cơ sở dữ liệu
Console.WriteLine(DataContext.Connection.ConnectionString);
2.2.2.3.3 Phương thức SelectAll
Mô tả: Trả về tất cả đối tượng của một lớp.
Cú pháp: virtual IList SelectAll(string orderByExpression)
Tham số:
orderByExpression: Thứ tự sắp xếp kết quả truy vấn, gồm tên trường và thứ tự sắp xếp ASC hoặc DESC, hoặc để chuỗi rỗng nếu không cần sắp xếp.
Trả về: Danh sách các đối tượng.
Ví dụ: IList users = SelectAll(“UserName ASC”);
2.2.2.3.4 Phương thức SelectBy
Mô tả: Truy vấn đối tượng theo điều kiện lọc.
Cú pháp:
virtual IList SelectBy(string searchCondition, string orderByExpression)
Tham số:
– searchCondition: Điều kiện lọc.
– orderByExpression: Thứ tự sắp xếp kết quả truy vấn, gồm tên trường và thứ tự sắp xếp ASC hoặc DESC, hoặc để chuỗi rỗng nếu không cần sắp xếp.
Ví dụ: userService.SelectBy(“GroupID = 1″, “UserName ASC”);
2.2.2.3.5 Phương thức SelectBy
Mô tả: Truy vấn đối tượng theo điều kiện lọc.
Cú pháp:
IList SelectBy(int fromItemNumber, int numberOfItems, string searchCondition, string orderByExpression)
Tham số:
– fromItemNumber: Bắt đầu chọn từ đối tượng thứ fromItemNumber.
– numberOfItems: Trả về số lượng numberOfItems đối tượng.
– searchCondition: Điều kiện lọc.
– orderByExpression: Thứ tự sắp xếp kết quả truy vấn, gồm tên trường và thứ tự sắp xếp ASC hoặc DESC, hoặc để chuỗi rỗng nếu không cần sắp xếp.
Ví dụ: userService.SelectBy(1, 20, “GroupID Null”, “UserName DESC”);
2.2.2.3.6 Phương thức Delete
Mô tả: Xóa bỏ đối tượng theo điều kiện lọc.
Cú pháp: virtual void Delete(string searchCondition)
Tham số:
searchCondition: Điều kiện lọc.
Ví dụ: userService.Delete(“GroupID = Null”);
2.2.2.3.7 Phương thức Delete
Mô tả: Xóa bỏ một tập các đối tượng.
Cú pháp: virtual void Delete(IList entities)
Tham số:
entities: Danh sách các đối tượng cần xóa bỏ.
Ví dụ: userService.Delete(View.SelectedItems);
2.2.2.3.8 Phương thức DeleteAll
Mô tả: Xóa bỏ toàn bộ các đối tượng của một lớp.
Cú pháp: virtual void DeleteAll()
Ví dụ: userService.DeleteAll();
2.2.2.3.9 Phương thức Insert
Mô tả: Thêm mới một đối tượng.
Cú pháp: virtual TEntity Insert(TEntity entity)
Tham số:
entity: Đối tượng mới.
Ví dụ:
User user = new User() { UserName = “X” };
userService.Insert(user);
2.2.2.3.10 Phương thức Update
Mô tả: Override phương thức này để thực hiện cập nhật thông tin một đối tượng.
Cú pháp: virtual void Update(TEntity entity, string searchCondition)
Tham số:
– entity: Đối tượng chứa thông tin cập nhật.
– searchCondition: Điều kiện lọc.
Ví dụ:
user.UserName = “Y”;
userService.Update(user, “UserID = 1″);
2.2.2.3.11 Phương thức NotifyDataChanged
Mô tả: Gọi phương thức này để thông báo mỗi khi dữ liệu vừa có sự thay đổi. Phương thức này kích hoạt sự kiện DataChanged trên các presenter và gọi phương thức FillData cập nhật lại dữ liệu trên toàn bộ các presenter có thi hành giao diện IObserver.
Cú pháp: void NotifyDataChanged()
Ví dụ:
UserGroup group = DataContext.GetTable().Where(obj => obj.GroupID == entity.GroupID).SingleOrDefault();
IList users = SelectBy(searchCondition, “”);
foreach (User user in users)
{
user.UserName = entity.UserName;
user.UserGroup = group;
}
DataContext.SubmitChanges();
NotifyDataChanged();
2.2.2.3.12 Phương thức ClearCache
Mô tả: Xóa bộ đệm dữ liệu.
Cú pháp: static void ClearCache()
2.2.2.3.13 Hàm delegate DataChangeHandler
Mô tả: Đăng ký nhận sự kiện mỗi khi dữ liệu có sự thay đổi.
Ví dụ: Đăng ký một hàm có tên FillData, phương thức này được kích hoạt mỗi khi dữ liệu có sự thay đổi.
public override void OnViewSet()
{
service = new UserGroupService();
service.DataChanged += new DataChangeHandler(FillData);
…
// Phương thức này thực hiện cập nhật lại thông tin trên view
private void FillData()
{
View.ListItem = service.SelectAll(“GroupName ASC”);
}
Có hai cách chặn bắt sự kiện dữ liệu có sự thay đổi, dùng hàm delegate DataChangeHandler hoặc dùng phương thức AttachObserver. Sự khác biệt của hai phương cách thức này là:
– Dùng hàm delegate: Chỉ presenter nào đăng ký mới nhận được thông báo.
– Dùng AttachObserver: Tất cả các presenter nào có đăng ký sẽ cùng nhận được thông báo.
2.2.2.4 Giao diện IObserver
Giao diện IObserver chỉ định nghĩa một phương thức duy nhất là FillData, phương thức được gọi mỗi khi lớp đối tượng Subject có sự thay đổi dữ liệu, dùng để thực hiện các thao tác cập nhật lại giao diện người dùng.
public interface IObserver
{
void FillData();
}
2.2.2.5 Giao diện ISubject
Định nghĩa các phương thức cho lớp Subject thi hành (dựa theo Observer pattern).
2.2.2.6 Lớp tổng quát Subject
Lớp đối tượng thi hành giao tiếp ISubject.
2.2.2.6.1 Phương thức AttachObserver
Mô tả: Đăng ký làm một observer, lớp đăng ký sẽ nhận được thông báo mỗi khi có sự thay đổi dữ liệu từ data service (xem mục 2.2.2.3.14).
Cú pháp: void AttachObserver(IObserver observer)
Tham số:
observer: Tên lớp đối tượng thi hành giao tiếp IObserver.
Ví dụ:
public class UserPresenter : GenericPresenter, IObserver
{
private IUserService userService;
public override void OnViewSet()
{
// Lấy single instance của UserService
userService = UserService.Instance;
// Dăng ký presenter này là observer nhận thông báo từ data service.
// Hàm FillData tự động được gọi mỗi khi dữ liệu có sự thay đổi.
userService.AttachObserver(this);
2.2.2.6.2 Phương thức DetachObserver
Mô tả: Hủy đăng ký một observer.
Cú pháp: void DetachObserver(IObserver observer)
Tham số:
observer: Tên lớp đối tượng thi hành giao tiếp IObserver.
Ví dụ: userService.DetachObserver(this);
2.2.2.6.3 Phương thức DetachAll
Mô tả: Hủy đăng ký toàn bộ observer.
Cú pháp: void DetachAll()
2.2.2.6.4 Phương thức NotifyObservers
Mô tả: Thông báo dữ liệu có sự thay đổi tới các observer đã đăng ký
Cú pháp: void NotifyObservers()
Ví dụ: userService.NotifyObservers();
2.2.2.6.5 Thuộc tính Observers
Mô tả: Trả về danh sách các observer đã đăng ký
Trả về: IList
Ví dụ:
// Tổng số các observer được đăng ký
Console.WriteLine(Observers.Count);
3 Nguồn thông tin tham khảo
– Kiến trúc Model-View-Presenter trong .NET (http://www.fpt.edu.vn/story/kien-truc-model-view-presenter-trong-net)
– Creating a generic Model-View-Presenter framework (https://dotnetchris.wordpress.com/2009/02/16/creating-a-generic-model-view-presenter-framework)
– Smart Client Software Factory (http://msdn.microsoft.com/en-us/library/ff648753.aspx)
– Tài liệu LINQ bản tiếng Việt (http://congthuong.googlecode.com/files/LINQ%20tieng%20viet.pdf)
– Dynamic LINQ (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx)
– Unity Application Block (http://msdn.microsoft.com/en-us/library/hh237493.aspx)
4 Ví dụ sử dụng
Tạo hai lớp User và UserGroup với các thuộc tính và quan hệ như sau:
Thiết kế các form cho đối tượng User và UserGroup với các thao tác thêm mới, cập nhật và xóa bỏ. Form UserGroup có thêm chức năng chọn thêm các thành viên vào nhóm chỉ định. Cụ thể có ba form như sau:
– frmUser quản lý danh sách người dùng.
– frmUserGroup quản lý danh sách nhóm người dùng.
– dlgUser để lựa chọn ra một số người dùng từ danh sách người dùng.
1 Tạo một solution với ba project tên là UI, Bussiness và Data (tên project tùy chọn) tương ứng với ba tầng View, Presenter và Model.
– Project UI chứa các form, là lớp giao diện tương tác với người phát triển (view).
– Project Business chứa các lớp xử lý nghiệp vụ (business).
– Project Data chứa các lớp đối tượng dữ liệu và các lớp dịch vụ truy cập dữ liệu (model).
Thêm tham chiếu tới thư viện MvpPattern vào References của ba project trên.
2 Trong project Data sử dụng LINQ để ánh xạ các bảng từ cơ sở dữ liệu quan hệ ra các đối tượng và để truy xuất cơ sở dữ liệu.
- Right click vào thư mục Data, chọn Add New Item, LINQ to SQL Classes, đặt tên cho file DBML.
- Vào menu View, chọn Server Explorer.
- Right click vào Data Connections, chọn Add Connection, chọn tên máy chủ và cơ sở dữ liệu.
- Kéo hai bảng Users và UserGroups thả vào file DBML.
- Lưu file DBML, các lớp đối tượng được tự động sinh mã trong file MvpExample.designer.cs, người phát triển có thể chỉnh sửa, bổ sung thêm mã bằng cách right click vào file DBML, chọn View Code.
3 Trong project Data, định nghĩa các giao diện và viết mã xử lý cho tầng dữ liệu.
Giao diện cho lớp UserService định nghĩa các phương thức thao tác với lớp User.
public interface IUserService : IGenericDataAccessService
{
// Thêm các thành viên vào nhóm người dùng
void AddToGroup(UserGroup group, IList users);
}
Thi hành giao diện IUserService và viết mã cho lớp UserService.
public class UserService : GenericDataAccessService, IUserService
{
// Constructor
public UserService() : base(new MvpExampleDataContext(LocalConfig.ConnectionString)) { }
Override các phương thức Insert, Update tương ứng.
Giao diện cho lớp UserGroupService định nghĩa các phương thức thao tác với lớp UserGroup.
public interface IUserGroupService : IGenericDataAccessService
{
}
Thực hiện các bước tương tự như với lớp UserService.
4 Trong project Bussiness, tạo các giao diện tương ứng cho các form trên.
Định nghĩa giao diện cho form frmUser và viết mã cho presenter:
public interface IUserView : IListManipulationView
{
IList GroupList { set; }
UserGroup CurrentGroup { get; }
}
UserPresenter quản lý giao diện IUserView.
public class UserPresenter : GenericPresenter, IObserver
{
private IUserService userService;
public override void OnViewSet()
{
userService = new UserService.Instance;
userService.AttachObserver(this);
groupService = UserGroupService.Instance;
}
public void FillData()
{
// Cập nhật thông tin của view ở đây
}
Định nghĩa giao diện cho hộp thoại dlgUser và viết mã cho presenter:
public interface IUserSelectionView : IListSelectionView
{
UserGroup CurrentGroup { get; set; }
}
UserSelectionPresenter quản lý giao diện IUserSelectionView.
public class UserSelectionPresenter : GenericPresenter
{
private IUserService userService;
public override void OnViewSet()
{
userService = UserService.Instance;
Định nghĩa giao diện cho form frmUserGroup và viết mã cho presenter:
public interface IUserGroupView : IListManipulationView
{
}
UserGroupPresenter quản lý giao diện IUserGroupView. Ngoài cách đăng ký làm một observer, còn cách khác là đăng ký một hàm nhận sự kiện. Trong ví dụ dưới đây hàm có tên là FillData.
public class UserGroupPresenter : GenericPresenter
{
private IUserGroupService groupService;
public override void OnViewSet()
{
groupService = new UserGroupService();
groupService.DataChanged += new DataChangeHandler(FillData);
}
private void FillData()
{
// Cập nhật thông tin của view ở đây
}
5 Trong project UI, tạo các form fmrUser, frmUserGroup và dlgUser.
Tạo form frmUser và thi hành giao diện IUserView
public partial class frmUser : Form, IUserView
Tạo hộp thoại dlgUser và thi hành giao diện IUserSelectionView
public partial class dlgUser : Form, IUserSelectionView
Tạo form frmUserGroup và thi hành giao diện IUserGroupView
public partial class frmUserGroup : Form, IUserGroupView
6. Tương tác giữa các tầng với nhau:
Khi người dùng cập nhật thông tin của một đối tượng, ấn nút Lưu, tầng UI sẽ gửi thông tin tới tầng như sau:
private void btnSave_Click(object sender, EventArgs e)
{
// CurrentItem là đối tượng hiện hành được cập nhật dữ liệu
CurrentItem.UserName = tbxName.Text.Trim();
CurrentItem.UserGroup = CurrentGroup;
// Phát sinh sự kiện lưu trữ gửi tới presenter
if (OnSaveEventHandler != null)
OnSaveEventHandler(this, e);
Tầng presenter lấy đối tượng vừa rồi, gọi phương thức Update của userService để cập nhật vào cơ sở dữ liệu:
public override void OnSaveEventHandler(object sender, EventArgs e)
{
userService.Update(View.CurrentItem, “UserID=” + View.CurrentItem.UserID);
}
Tải mã nguồn ví dụ:
– MvpPatternExample.rar (http://www.mediafire.com/?fqcznsk5s4euvu4)
– MvpPatternDIPExample.rar (http://www.mediafire.com/?u91e7keg8qr8mv5)
ManNT – R&D, HueCIT (bài cho HW)
09/01/2013
[*] Nguyên lý đảo ngược phụ thuộc (Dependency Injection): Lớp cấp cao không nên phụ thuộc vào lớp cấp thấp, cả hai nên phụ thuộc vào một lớp tổng quát (abstract class/interface); và, lớp tổng quát (abstract) không nên phụ thuộc vào lớp cụ thể (concrete), ngược lại lớp cụ thể nên phụ thuộc vào lớp trừu tượng. Do lớp tổng quát ít có sự thay đổi, ổn định hơn so với lớp cụ thể thường xuyên có sự thay đổi, chỉnh sửa nâng cấp; và khi phụ thuộc vào các lớp tổng quát, hệ thống vẫn hoạt động bình thường nếu có sự thay đổi diễn ra tại một lớp cụ thể nào đó. Bởi vậy, cần đảo ngược sự phụ thuộc đó thành lớp cụ thể phụ thuộc vào lớp tổng quát.
Góc nhìn ADN về gốc rễ dân tộc và ngôn ngữ Trung Quốc
Xem bản đồ ADN thể hiện các luồng thiên tỉ của nhân loại ở châu Á sau:
(Lấy từ mạng của TQ: http://www.tianyabook.com/qita/zhongguorencongnalilai/4.html)

– Từ bản đồ trên nhận thấy nguồn gốc các dân tộc trên lục địa TQ là đa nguyên, khá phức tạp.
Hai đường thiên di lớn của giống người cổ đại Homo sapiens vào TQ là:
1- Nhóm O1 và O2a xuất phát từ đồng bằng sông Hồng thiên di lên phía Bắc, tới vùng Lưỡng Quảng khoảng 3 vạn năm trước, rồi chia 2 nhánh tới vùng đồng bằng Trường Giang khoảng 1,5 vạn năm trước
– Nhóm O1 và O2a tiếp tục đi dọc bờ biển lên phía bắc tới vùng Sơn Đông và cửa sông Hoàng Hà (Hà Bắc) khoảng 1 vạn năm trước.
– Nhóm O2b tách ra từ O2a đi tiếp tới bán đảo Triều tiên và tây nam quần đảo Nhật Bản khoảng 5000 năm trước.
2- Nhóm O3 xuất phát từ Miến Điện vòng qua sườn đông Hy Mã Lạp Sơn tới cao nguyên Tây Tạng khoảng 2 vạn năm trước, tới vùng sông Khương khoảng 1,5 vạn năm trước, đi tiếp tới vùng lưu vực Hoàng Hà khoảng 8000 năm trước và “chạm trán” các nhóm O1,O2 tại vùng phía bắc Hà Bắc.
– Điểm “chạm trán” này ở khoảng vùng Bản Kiều, phía bắc Bắc Kinh, nơi theo truyền thuyết thì Hoàng Đế (nhóm tộc gốc vùng Hoàng Hà) đã đánh bại Viêm Đế gốc phương Nam và “hòa nhập” các nhóm tộc, hình thành nên dân tộc “Hoa Hạ” ban đầu.
– Theo Sử Kí sách ẩn của Tư Mã Trinh thì Viêm Đế Thần Nông vốn sinh ra ở Hồ Bắc, táng ở Hồ Nam, nên Thần Nông Thị chắc là gốc Bách Việt ở vùng Trường Giang (thuộc nhóm O1 hay O2a).
Bây giờ thử bàn về nguồn gốc ngôn ngữ Hán:
– Nhóm Tạng Miến (O3) của Hoàng Đế là nhóm chiến thắng trong cuộc “hòa nhập” với nhóm phương nam của Viêm Đế nên không có gì ngạc nhiên khi ngôn ngữ của kẻ chiến thắng (họ Hán Tạng) là ngôn ngữ chính thống của cả tộc Hoa Hạ, từ đây xin gọi là Hán Tộc, mặc dù thực ra thì Hán Thủy là nơi xuất phát của Viêm Đế – Thần Nông thị, còn Hoàng Đế thường được coi là gốc ở vùng Hoàng Hà.
– Tuy nhiên nhóm phương Nam tới lục địa TQ sớm hơn và do đó có khả năng là nhóm đông hơn, văn hóa phát triển sớm hơn. Sử TQ từng nói nhiều về nền văn minh nông nghiệp do Thần Nông khai sáng, trong khi Hoàng Đế thì chỉ nức tiếng về những chiến công quân sự: đánh bại tộc Cửu Lê của Xi Vưu ở trận Trác Lộc, đánh bại Viêm Đế ở trận Bản Tuyền .v.v. Có thể so sánh với các tộc Mông Cổ và Mãn Thanh từng thống trị TQ nhưng lại là sắc dân thiểu số và nền văn minh vốn kém hơn, chỉ chiến thắng nhờ sự thiện chiến cùng với sự chia rẽ, tự suy yếu của các nhóm tộc phía Nam.
– Giới ngôn ngữ học cho rằng 6000 năm trước thì vùng Trường Giang xuống phía Nam còn nói chung 1 thứ tiếng, gọi là tiếng Nam Á. Các nhóm tộc phía nam TQ tức là các nhóm tộc gốc “Bách Việt”, ngôn ngữ của họ vốn gốc rễ từ họ Nam Á, các nhóm tộc này là cư dân ban đầu ở lục địa TQ và có khả năng phát triển sớm hơn nhóm Hán Tạng, vậy mà không lẽ các vết tích ngôn ngữ của họ Nam Á đã biến mất sạch trơn trong Hán ngữ sau cuộc “hòa nhập” Viêm-Hoàng ? Chắc là không ! Ví dụ điển hình là chữ “Giang 江” (sông, krông) gốc phương nam mà nhiều nhà nghiên cứu đã dẫn nên tại hạ xin miễn nhắc lại.
– Các khảo cứu của nhà nghiên cứu Nguyễn Cung Thông và tại hạ chính là tìm lại các vết tích phương Nam trong Hán Ngữ trung đại và hiện đại, mà những kẻ chiến thắng đã cố tình xóa bỏ (xóa không được thì nhận luôn là của mình
), là một việc làm khoa học khách quan, hoàn toàn không phải là một sự “ngộ nhận đáng thương”, “chủ nghĩa dân tộc cực đoan” như nhiều vị đã lợi dụng sự tự do trên các diễn đàn mạng lớn giọng dè bỉu .
Bây giờ hãy nghiên cứu thêm bảng thông tin về các nền văn minh thời đồ đá mới ở TQ, chú ý cột cuối bên phải có ghi các thông tin về nhóm ADN (nhiễm sắc thể Y) của các tộc sở hữu nền văn minh đó:
Tư liệu từ trang http://www.tianyabook.com/qita/zhongguorencongnalilai/5.html

– Nhóm O1 là chủ nhân nền văn hóa Từ Sơn, ở Kí châu (Hà Bắc)
– Nhóm O1+O2 là chủ nhân nền văn hóa Đại Bộn Khanh, Lương Chử ở Dương Châu (Khoảng từ bắc nước Việt cổ tới nam Giang Tô)
– Nhóm O1+O2+O3 là chủ nhân nền văn hóa Hồng Sơn ở Yên Sơn, U Châu
– Nhóm O2+O3 là chủ nhân nền văn hóa Lý Gia Thôn ở Lương Châu, từ phía nam Tần Lăng tới phía nam Vân Quý (tức Vân Nam-Quý Châu), quá độ từ nhóm Môn-Khmer sang Tạng Miến.
– Còn lại là nhóm O3 chủ nhân các nền văn hóa Ngưỡng Thiều, Đại Khê, Bùi Lý Cương, Đào Tự Long Sơn, Đại Văn Khẩu, Long Sơn.
Nhìn qua bảng này thì các nhóm Hán Tạng (O3) chiếm phần lớn các nền văn hóa, nhưng cần lưu ý đây là nhóm “xâm lấn”, không loại trừ khả năng một số vùng trước khi nhóm O3 đến thì đã có nền văn hóa của các nhóm O1, O2 sau đó bị O3 che lấp đi, việc tồn tại các nhóm giao thoa O2-O3 và O1-O2-O3 chứng tỏ điều này.
Bây giờ hãy chú ý đến văn hóa Lý Gia Thôn, vốn gốc là Môn-Khmer O2 sau đó đã bị chuyển hóa thành Tạng Miến O3 (nguyên văn chữ Hán trong bảng “Mạnh Cao Miên tộc quần hướng Tạng Miến tộc quần quá độ nhân quần”).
Phạm vi của văn hóa này rất rộng, từ phía nam Tần Lăng ở Thiểm Tây xuống đến nam Vân Quý, tức là tiếp liền với Lào-Việt Nam hiện nay.
Thông tin này cũng phù hợp thông tin trong Hậu Hán thư cho biết người Lạc Việt từng định cư ở huyện Trung Lư nay là Nam Chương, gần phía bắc của Hồ Bắc, gần địa giới phía nam Thiểm Tây, vào khoảng đầu công nguyên (Truyện Tang Cung ghi năm 12 Hán Quang Võ, trước khởi nghĩa của Hai Bà Trưng). Vùng này cũng sát cạnh Liệt Sơn-Tùy Châu là quê hương Thần Nông là ông tổ của Lạc Long Quân mà chính sử Việt Nam có ghi. Nhóm Lạc Việt ở Trung Lư này rất có thể thuộc ngữ hệ Môn-Khmer, và cùng nhóm ADN O2 như người Việt (Kinh).
Vùng Hồ Bắc-Hồ Nam chính là nằm trong dải đất từ Tần Lăng xuống phía nam Vân Quý, nếu khoảng 5000 năm về trước, tức từ thời Thần Nông trở về trước, vốn là đất của các tộc Môn-Khmer O2, thì việc chữ Giang 江 có âm cổ là krông, giống hệt tiếng của nhiều dân tộc Tây Nguyên VN hiện nay dùng gọi “sông”, là một việc hết sức tự nhiên ! Và việc tên gọi các vua dòng Viêm Đế: Thần Nông, Đế Đồi, Đế Thừa, Đế Minh, Đế Lai … Đế Du Võng có kết cấu thuận như tiếng Việt (đặt địa vị trước tên riêng) cũng không có gì lạ nữa.

