CÔNG VIỆC CỦA CHÚNG TÔI

+ Đào tạo & hỗ trợ thi & Cấp chứng chỉ Ứng dụng CNTT cơ bản, nâng cao
+ Cung cấp dịch vụ Thiết kế - Lập trình web
+ Các giải pháp triển khai - quản trị hệ thống mạng doanh nghiệp
+ ĐÀO TẠO CHUYÊN NGHIỆP: LẬP TRÌNH (C, .Net, ASP.net, PHP, Thiết kế Đồ họa

Kiểu dữ liệu Generics và Iterators trong C#

Generics là các cấu trúc dữ liệu mà cho phép bạn dùng lại các mã giống nhau cho các kiểu khác nhau giống như class, interface, Generics được dử dụng tốt nhất khi làm việc với các mảng và các tập hợp liệt kê. Iterators là các khối của đoạn mã mà có thể được lặp lại thông qua các giá trị của tập hợp.
 1.      Giới thiệu:
Stack stack = new Stack();
for (int i = 0; i < 10; i++) stack.Push(i);
foreach (int i in stack) Console.Write("{0} ", i);
Output: 0 1 2 3 4 5 6 7 8 9
            Trong đoạn code trên, bạn có thể thấy một kiểu khai báo mới: "Stack", đó chính là generics. Nhờ nó, trình dịch sẽ buộc kiểu của dữ liệu bạn đưa vào stack qua hàm Push() phải phù hợp kiểu đã định (ở đây là int). Cái này giống với template trong STL. Generics có thể áp dụng cho class, struct, interface, delegate, và methods.
            Iterator được cải tiến để có thể làm việc được với generics. Trong dòng lệnh cuối cùng ở trên, lệnh foreach đã được viết rất đơn giản vì biến i có kiểu phù hợp với stack.
2. Mục đích:
Các generic trong C# là các cấu trúc mà cho phép bạn dùng lại các tính năng đã được định nghĩa cho các kiểu dữ liêu khác nhau trong C#.
Trong một chương trình C# mà sử dụng một mảng kiểu Object để lưu trữ tên một tập hợp của các sinh viên. Tên được đọc từ người dùng do các kiểu giá trị đều được cho phép chuyển đổi về kiểu object. Trong trường hợp này khi người dùng nhập vào một giá trị kiểu numeric (kiểu số) thì trình biên dịch cũng không có bất kỳ sự kiểm tra nào.
Để đảm bảo đúng kiểu dữ liệu, C# cung cấp generics, nó là một tính năng được tích hợp trong C# mà cho phép bạn định nghĩa được kiểu dữ liệu mẫu gốc trên nó các kiểu dữ liệu được kiểm tra chuẩn kiểu dữ liệu sau này.
3. Các namespace cho Generics.
Các generic là một loại cấu trúc dữ liệu mà có thể làm việc với các kiểu giá trị cũng như các kiểu tham chiếu. Bạn có thể định nghĩa một class, interface, structure and delegate như một kiểu dư liệu trong C#. Namespace System.Collections.ObjectModel cho phép bạn tạo động và tập hợp các generic duy nhất có khả năng đọc. Namespace System.Collections.Generic gồm các class và interface cho phép bạn định nghĩa tập hợp các generic có thể sửa đổi. 
4. Việc tạo các generic:
Một sự khai báo các generic luôn luôn chấp nhận một tham số kiểu. Nó là một phần nắm giữ kiểu dữ liệu được trả về. Kiểu được chỉ định duy nhất một kiểu generic được nói tới hoặc hàm khởi tạo nó là một kiểu trong chương trình.
Cấu trúc:
6. Tác dụng của Generic:
Generic đảm bảo chuẩn kiểu dữ liệu lúc biên dịch. Generics cho phép bạn dùng lại mã trong một nền tảng mà không có khuôn mẫu hoặc chuyển đổi. Một sự định nghĩa kiểu generic là khả năng dùng lai với các kiểu dữ liệu khác nhau nhưng không chấp nhận các giá trị của một kiểu đơn cùng một thời gian.
Một số tính năng của Generic:
Ø  Tăng khả năng thực thi vì không mất thời gian và bộ nhớ cho việc casting và boxing khi tạo một generic.
Ø  Đảm bảo kiểu mẫu lập trình mạnh
Ø  Hạn chế các lỗi run-time mà có thể xảy ra trong quá trình boxing và casting.
6. Các class Generic:
Các class Generic định nghĩa các tính năng mà có thể dùng cho bất cứ kiểu dữ liệu nào.Các class là được khai báo với việc khai báo một class sau đó là tham số kiểu được bao trong hai dấu < >. Lúc khai báo class generic bạn có thể gán thêm một số hạn chế hoặc điều kiện cho tham số kiểu bằng viẹc sử dụng từ khóa where. Hơn nữa việc gán thêm hạn chế và các điều kiện vào tham số kiểu là tùy ý.
Các class Genric có thể được lồng với các class generic hoặc không generic khác, Hơn nữa bất kỳ class được lồng trong một class generic khác và khác tham số kiểu thì tham số kiểu của class bên ngoài sẽ được gán lại cho class lồng bên trong.
7. Các điều kiện của tham số kiểu:
Bạn có thể gán các điều kiện cho tham số kiểu lúc khai báo một kiểu genneric. Một ép buộc là một là một hạn chế được áp đạt lên các kiểu dữ liệu của tham số kiểu. Các ép buộc được chỉ định bằng cách chỉ định từ khóa where. Nó được sử dụng khi người lập trình muốn giới hạn kiểu dữ liệu trên tham số kiểu để đảm bảo sự toàn vẹn và tin cậy của dữ liệu trong một tập hợp.
8. Việc kế thừa các class Generic:
Ø  Một class generic có thể kế thừa từ bất cứ class generic hoặc không phải class generic nào trong C#. Khi đó một class generic đóng vai trò cả hai giống như một class cơ sở hoặc class dẫn xuất.
Ø  Thực hiện các thao tác bình thường như thao tác với các class kế thừa nhau thông thường.
9. Các phương thức Generic.
Ø  Các phương thức generic sử lý các dữ liệu của các kiểu dữ kiệu là duy nhất khi các biến lưu trữ kiểu dữ liệu này, Một generic được khai báo với danh sách tham số kiểu được bao trong  2 dấu < >.
Ø  Việc định nghĩa các phương thức với các tham số kiểu cho phép bạn gọi tới phương thức với các kiểu khác nhau mọi lúc.
Ø  Bạn có thể khi báo một generic class bên trong một class là generic class hoặc class thông thương. Khi bạn khai báo một phương thức được khai báo trong một class generic đươc khai báo thì thân của phương thức thể hiện cả hai tham số kiẻu của phương thức và của class.         
10. Các interface Generic.
Ø  Các interface Generic là được dùng cho tập hợp các generic hoặc các class generic việc hiển thị các thành phần trong tập hợp. Bạn có thể sử dụng các class generic với các interface  ngăn chặn các toán tử boxing và casting trên các kiểu giá trị.
Ø  Các class interface co thể thực thi các giao diện generic bằng việc thông qua sự trả về của các tham số được chỉ định trong interface. Tương tự thế các class generic cũng thực thi sự kế thừa.
11. Mục đích của Iterator.
Ø  Trong một hoàn cảnh mà có một người muốn nhớ một cuốn sách của 100 trang. Nhiệm vụ cuối cùng của người này là nhắc lại mỗi trang trong 100 trang đó.
Ø  Tương tự người này phải nhắc lại số trang, một iterator trong C# hỗ trợ việc đi tắt  thông qua một danh sách các giá trị hoặc một tập hợp. nó là một khối của đoạn code khi mà dùng vòng lặp foreach gọi tới một tập hợp các giá trị theo một khuôn mẫu có tuần tự.
Ø  Ví dụ như một người lập trình lưu trữ các giá trị thông qua sự tuần tự các giá trị sử dụng ỉterator để so sánh các giá trị. 
12. Iterator:
Ø  Một iterator không phải là một thành phần dữ liệu nhưng nó là một cách của việc truy suất đến các phần tử. Nó có thể là một phương thức một khả năng truy suất get hoặc một một toán tử mà cho phép bạn đánh dấu các giá trị trong một tập hợp. Các Iterator là chỉ định cái cách mà các giá trị được sinh ra khi mà vòng lặp foreach truy suất đến các phần tử trong một tập hợp.
Ø  Chúng giữ lại một phần các phần tử trong tập hợp sau đó nó có thể lấy về các giá trị này khi cần đến.
13. Tác dụng:
Ø  Cung cấp một sự đơn giản và nhanh hơn theo cách nhắc lại các giá trị trong tập hợp.
Ø  Giảm bớt sự phức tạp của việc cung cấp một sự liệt kê cho một tập hợp.
Ø  Iterator có thể trả về một lượng lơn các giá trị.
Ø  Iterator có thể được đánh giá và trả về duy nhất các giá trị mà nó cần thiết.
Ø  Iterator có thể trả về các giá trị mà không tốn bộ nhớ bằng việc gọi tới duy nhất một giá trị trong danh sách.
14. Sự thực thi:
Ø  Iterator có thể được thực hiện bằng phương thức GetEnumerator() mà trả về một tham chiếu tới interface IEnumerator.
Ø  Khối iterator sử dụng từ khóa yield. Từ khóa yield return là trả về các giá trị khi đó từ khóa yield break là kết thúc của sử lý iterator.
Ø  Một cách khác để tạo là bằng việc tạo một phương thức kiểu trả về là interface IEnumerable. Đây được gọi là một iterator có tên.Iterator có tên chấp nhận tham số mà được sử dụng cho việc quản lý điểm bắt đầu và điểm kết thúc vủa vòng lặp foreach.  
Bài thực hành số 14
Generic và Iterator
1.      Generic
Tóm tắt lý thuyết: Lập trình generic tiết kiệm được khá khá thời gian lập trình, và tính tái sử dụng code rất cao. Trong C#, bạn có thể lập trình Generic với Class, Struct, Function.
Generics rất hữu ích vì nó cung cấp một khả năng mạnh mẽ để kiểm tra kiểu dữ liệu trong lúc biên dịch, sử dụng ít các phép ép kiểu giữ các kiểu dữ liệu khác nhau, giảm việc ép kiểu lúc chạy.
1.1 Tại sao dùng generics?
Nếu không có generics, để mô tả dữ liệu không xác định (dữ liệu có kiểu tổng quát nào đó), chúng ta phải dùng kiểu object. Ví dụ, lớp Stack chứa dữ liệu là một mảng các object, và nó có hai phương thức Push và Pop, sử dụng object như là kiểu dữ liệu đầu vào.
Mặc dù chúng ta dùng kiểu object để lưu trữ dữ liệu một cách rất mềm dẻo, tuy nhiên lại xuất hiện một số hạn chế. Ví dụ, chúng ta có thể đẩy vào Stack một giá trị thuộc kiểu bất kì, ví dụ Customer. Khi đối tượng này được lấy ra ví dụ bằng lệnh Pop, chúng ta bắt buộc phải ép kiểu trở lại, điều này làm giảm hiệu năng của hệ thống do xuất hiện các phép kiểm tra kiểu dữ liệu.
Nếu giá trị truyền vào là kiểu tham trị (value type), nó sẽ được tự động gọi lại (boxed). Khi lấy lại, giá trị này sẽ được tự động mở gói (unboxed), và đây là phép ép kiểu không an toàn (boxingunboxing - khái niệm?)
 Tất cả các phép boxing và unboxing, ngoài việc kiểm tra kiểu dữ liệu, còn mất các phép toán khởi tạo bộ nhớ động cho việc box/unbox.
Một vấn đề nữa là chúng ta có thể chuyển kiểu nhầm. Ví dụ, bạn lưu trữ vào Stack một đối tượng Customer, nhưng lại lấy ra một string, khi đó ngoại lệ InvalidCastException sẽ được ném ra, do chúng ta không thể chuyển Customer về string được.
Mọi việc sẽ ổn hơn nếu chúng ta có thể chỉ đích xác kiểu dữ liệu mà Stack lưu trữ. Generics cho phép chúng ta làm điều đó
1.2 Tạo và sử dụng Generics
Ví dụ sau đây mô tả cách tạo một lớp generic Stack nhận kiểu dữ liệu T như là tham số đầu vào. Kiểu này được đặt trong cặp dấu <> đi ngay đăng sau tên lớp. Thay vì chuyện cần có phép ép kiểu từ kiểu object, mỗi thể hiện Stack chỉ làm việc với kiểu dữ liệu được chỉ định ra lúc tạo, và không cần đến phép ép kiểu. T hoạt động như là thành phần tạm, cho đến khi một thể hiện nào đó của Stack được tạo ra
Khi lớp Stack được dùng, một kiểu dữ liệu cụ thể nào đó sẽ thay thế T. Xem ví dụ sau:
Kiểu Stack được gọi là kiểu đã khởi tạo (constructed type). Trong kiểu này, tất cả chỗ nào xuất hiện T đều được thay thế bởi int. Lúc đó mảng sẽ lưu trữ là mảng các số nguyên, chứ không phải là mảng các đối tượng, và sẽ hiệu quả hơn nhiều so với việc lưu trữ và xử lí mảng đối tượng. Tất nhiên, các hàm Push và Pop của Stack cũng hoạt động với kiểu dữ liệu int, cho phép kiểm soát lỗi không tương thích kiểu lúc biên dịch, và tránh được phép ép kiểu lúc chạy chương trình.
Generics cho phép kiểm tra kiểu ngay khi biên dịch, có nghĩa là chúng ta không thể nhầm lẫn trong việc xử lí dữ liệu được,. Tất cả những lỗi này sẽ được thông báo ngay bởi bộ biên dịch. Hãy xem ví dụ sau.
   1:   Stack stack = new Stack();
   2:  stack.Push(new Customer());
   3:  Customer c = stack.Pop();
   4:  stack.Push(3);      // Type mismatch error
   5:  int x = stack.Pop();    // Type mismatch error
Generics có thể sử dụng nhiều kiểu dữ liệu đầu vào. Lớp Stack dùng một kiểu dữ liệu đầu vào, nhưng lớp Dictionary lại có hai kiểu dữ liệu đầu vào, một dành cho kiểu dữ liệu của khóa, và một dành cho kiểu dữ liệu của giá trị khóa.
   1:   public class Dictionary
   2:  {
   3:      public void Add(K key, V value) {...}
   4:      public V this[K key] {...}
   5:}
Tất nhiên, khi sử dụng chúng ta phải cung cấp cả hai kiểu dữ liệu này
Ví dụ


Ràng buộc dữ liệu

Nói chung, các lớp generic sẽ thực hiện nhiều hành động hơn là chỉ lưu trữ dữ liệu. Thực tế là các lớp generic sẽ muốn triệu gọi các phương thức có liên quan đến việc xử lí đối tượng có kiểu với tham số generic truyền vào. Xem ví dụ sau:

Vì kiểu dữ liệu của K có thể là bất cứ kiểu gì, do đó chúng ta chỉ có thể dùng phương thức có trong Object, nghĩa là lớp nào cũng hỗ trợ, ví dụ như các hàm Equals, GetHashCode, và ToString; nếu chúng ta dùng hàm khác (trong ví dụ trên là CompareTo) thì không thể đảm bảo rằng kiểu nào của K cũng hỗ trợ, nên sẽ có lỗi biên dịch. Tất nhiên, nếu muốn thì lúc này phải ép kiểu, ví dụ như sau:
Tới đây, vấn đề cũ lại xảy ra: mất thêm chi phí ép kiểu và có thể có ngoại lại ném ra nếu trong trường hợp chúng ta không ép kiểu được.
Để giải quyết vấn đề này, C# cung cấp 1 cách kiểu tra kiểu tại thời điểm design, đồng thới làm giảm bớt ép kiểu, đó là danh sách các ràng buộc (constraints) đối với mỗi loại tham số. Mỗi kiểu tham số đầu vào sẽ phải thỏa mãn các ràng buộc nào đó để mà có thể trở thành kiểu tham số thực. Tham số này được cung cấp bằng từ khóa where, theo sau bởi tên kiểu và dấu hai chấm, đến kiểu lớp, kiểu giao tiếp ràng buộc, cách nhau bởi dấu phảy
Cú pháp where
Chú ý :
Chúng ta có thể chỉ định nhiều ràng buộc về giao tiếp và kiểu, nhưng chỉ có 1 ràng buộc bề lớp. Các ràng buộc kiểu khác nhau cách nhau bởi mệnh đề where. Ví dụ dưới đây, kiểu K có 2 ràng buộc giao tiếp, trong khi kiểu E có 1 ràng buộc lớp và 1 ràng buộc khởi tạo.
Ràng buộc khởi tạo new() ở ví dụ trên chỉ ra rằng kiểu truyền vào cho E phải có hàm tạo không tham số, public, do đó cho phép lớp generic có thể gọi hàm tạo này để tạo thể hiện cho lớp. phần này tra ở Help.

Phương thức generic

Trong một số trường hợp thì chúng ta không cần kiểu generic cho 1 lớp, mà chỉ cần cho một phương thức nào thôi. Trong trường hợp này thì chúng ta sẽ dùng phương thức generic. Ví dụ, với lớp Stack ở trên, một thao tác hay làm đó là đẩy vào trong stack nhiều phần tử 1 lúc, nghĩa là trong 1 lời gọi hàm sẽ thao tác với nhiều phần tử. Chẳng hạn, để tạo một Stack, chúng ta muốn rằng sẽ đẩy vào 1 mảng các số nguyên, vậy phương thức sẽ như sau:
Lời gọi tương ứng sẽ là :
Tuy nhiên, cách làm này chỉ đúng với Stack. Bây giờ, chúng ta sẽ phải viết một phương thức generic, sử dụng chung kiểu dữ liệu T đối với lớp generic. Đoạn mã như sau:
Lời gọi hàm tương ứng là

Lập trình Generic với Struct.
Nhìn chung, ko có gì khác biệt trong cách lập trình Generic Struct và Generic Class, ví dụ sau là Struct
Couple:
Ví dụ


2. Giới thiệu Iterator
Câu lệnh foreach của C# được dùng để duyệt lặp đi lặp lại qua những phần tử trong một tập liệt kê được. Để trở thành một tập liệt kê được, tập đó phải phải có phương thức GetEnumerator trả về enumerator (toán tử liệt kê). Nói chung, trên thực tế toán tử liệt kê rất khó cài đặt, thế nhưng công việc này sẽ đơn giản hơn với việc dùng iterator.
Một iterator là một khối lệnh cho phép yield (tạo ra, sinh ra) một dãy các giá trị đã được sắp xếp. Một iterator được phân biệt với khối lệnh bình thường bằng một hay nhiều từ khóa yield:
Ø  Lệnh yield return chuyển đến giá trị tiếp theo của iteration
Ø  Lệnh yield break chỉ ra iterator đã hoàn thành.
Một iterator có thể được dùng như là thân hàm hoặc là giá trị trả về của hàm trong lớp có cài đặt giao tiếp enumerator hoặc enumerable.
Ø  Giao tiếp enumerator là System.Collections.IEnumerator và được thiết lập từ System.Collections.Generic.IEnumerator.
Ø  Giao tiếp enumerable là System.Collections.IEnumerable và được thiết lập từ System.Collections.Generic.IEnumerable.
Ø  Một điều quan trọng đó là một iterator không phải là một thành viên của lớp, nhưng đó là một cách cài đặt hàm thành viên. Một thành viên được cài đặt thông qua iterator có thể được viết đề bởi các thành viên khác mà có hay không có sự cài đặt với iterator.
Ø  Lớp Stack dưới đây cài đặt giao tiếp GetEnumerator bằng cách sử dụng iterator. Iterator này cho phép duyệt stack từ đỉnh về đáy.
Khi đó, chúng ta sẽ sử dụng được lệnh foreach đối với Stack. Xem đoạn lệnh minh họa sau:
Kết quả đầu ra là: 9 8 7 6 5 4 3 2 1 0
Lệnh foreach sẽ gọi phương thức GetEnumerator để lấy về một toán tử liệt kê. Tất cả các hàm này đều không có tham số truyền vào, mặc dù có thể có nhiều hàm như vậy. Trong trường hợp đó, chúng ta hiểu như là lớp sẽ cho phép liệt kê các thành phần của nó theo các thứ tự (hướng) liệt kê khác nhau. Xem ví dụ dưới đây:
Phương thức TopToBottom trả về this, vì bản thân lớp Stack đã là một lớp liệt kê được. Phương thức BottomToTop trả về một kiểu liệt kê khác. Ví dụ minh họa sử dụng lớp Stack như dưới đây:

Trả về kiểu IEnumerable hay IList?

Câu hỏi: Tại sao lại trả về IEnumerable mà ko phải là IList ? Hoặc rộng hơn là tại sao lại chọn IEnumerable thay vì các kiểu collection khác hay 1 class cụ thể?
Vấn đề: nhiều bạn viết code thường trả về kiểu List Có lẽ là vì kiểu List có thể làm được mọi thứ nhanh chóng dễ dàng. Nhưng khi dùng tool như Resharper, có thể thấy rằng Reshaper khuyến nghị chúng ta nên trả về IEnumerable. Tại sao lại như vậy?
Giải thích: 1 nguyên tắc khi thiết lập Interface, đó là trả về most restricted type, vì vậy luôn trả về kiểu List là 1 thói quen xấu và tùy tiện. Trả về IEnumerable có 2 lợi ích:
  • Ngăn chặn những thao tác chỉnh sửa lên read-only collection, ví như khi ta trả về tập hợp với mục đích hiển thị, nhưng sau đó lại cố gắng add thêm item vào, trình biên dịch sẽ báo động cho chúng ta về lỗi tư duy này ngay lập tức
  • Không bị giới hạn size như với Array
  •  

Vài tóm tắt về ột số phương pháp lập trình (truyền thống, hướng thủ tục, hướng module, hướng đối tượng)

1. Lập trình truyền thống không có cấu trúc

Đây là phương pháp lập trình truyền thống cho những người mới bắt đầu học lập trình, không sử dụng hàm, tất cả dòng lệnh đều viết trong file từ trên xuống dưới, dữ liệu đều dùng chung và tất cả các biến đều ở dạng toàn cục.
Ví dụ: Chương trình in ra danh sách sinh viên
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//----------------------------------------//
// Chương trình in ra danh sách sinh viên //
//----------------------------------------//
  
// Danh Sách Sinh Viên
$sinhvien = array(
    'Nguyễn Văn A',
    'Nguyễn Văn B',
    'Nguyễn Văn C',
    'Nguyễn Văn D',
    'Nguyễn Văn E',
    'Nguyễn Văn F',
    'Nguyễn Văn G',
    'Nguyễn Văn H',
    'Nguyễn Văn I',
    'Nguyễn Văn K',
    'Nguyễn Văn L',
    'Nguyễn Văn M'
);
  
// In ra danh sách sinh viên
echo 'DANH SÁCH SINH VIÊN';
for ($i = 0; $i < $sinhvien; $i++){
    echo 'Sinh Viên ' . $sinhvien[$i];<br>
}
Ưu điểm: Viết rất nhanh, chương trình chạy cũng rất nhanh vì không phải thông qua giai đoạn gọi hàm, gọi đối tượng.
Nhược điểm:
  • Gặp khó khăn khi xây dựng các chương trình lớn, vì dòng lệnh rất dài rất khó bảo trì và quản lý dòng code.
  • Khi chương trình có những dòng lệnh được lặp lại thì phải copy thành nhiều chỗ, và khi sửa một chỗ thì phải sửa tất cả các chỗ còn lại.
  • Chỉ viết được các chương trình nhỏ.
  • Chương trình không khoa học, rất khó sửa chữa và bảo trì.

2. Lập trình truyền thống hướng thủ tục

Phương pháp lập trình thủ tục cũng là một phương pháp lập trình truyền thống, nó lấy các hàm làm nền tảng cơ bản để xây dựng chương trình, chương trình sẽ được phân nhỏ thành các hàm và mỗi hàm sẽ có chức năng riêng biệt. Các hàm sẽ gọi qua lại lẫn nhau để tạo thành một hệ thống của chương trình. Vì sử dụng hàm làm nền tảng nên có sử dụng khái niệm biến toàn cục và biến địa phương.

 

Hình minh họa lập trình hướng thủ tục
Ví dụ: Chương Trình Quản Lý Sinh Viên
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//----------------------------------------//
// Chương trình Quản Lý Nhân Viên//
//----------------------------------------//
  
// Hàm kết nối cơ sở dữ liệu
function connect_db()
{
    // Dòng lệnh ...
}
  
// Hàm ngắt kết nối cơ sở dữ liệu
function disconnect_db()
{
    // Dòng lệnh ...
}
  
// Thêm Sinh Viên
function add_student($id, $name, $address, $birthday, $gender)
{
    connect_db();
  
    // Dòng lệnh ...
  
    disconnect_db();
}
  
// Xóa sinh viên
function delete_student($id)
{
    connect_db();
  
    // Dòng lệnh ...
  
    disconnect_db();
}
  
// Sửa sinh viên
function edit_student($id, $name, $address, $birthday, $gender)
{
    connect_db();
  
    // Dòng lệnh ...
  
    disconnect_db();
}
Ưu điểm: 
  • Chương trình được tổ chức khoa học hơn nên dễ quản lý và bào trì
  • Có thể thực hiện được nhiều chương trình lớn hơn
Nhược điểm:
  • Cách tiếp cận đôi khi không phù hợp với thực tế, các diễn đạt thiếu tự nhiên.
  • Khó mô tả được các hoạt động của thế giới tự nhiên
  • Bảo mật kém

3. Lập trình truyền thống hướng modun

Phương pháp lập trình truyền thống này lấy ý tưởng đóng hộp, các hàm có chức năng giống nhau sẽ được gom lại thành một modun độc lập, khi cần sử dụng module nào sẽ gọi tới module đó nên một chương trình có thể có nhiều module chứ không riêng lẻ độc lập.
Hình minh họa lập trình hướng module
Ví dụ: Cấu trúc chương trình phần mềm kế toán
File maths.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//------------------//
// FILE maths.php --//
//------------------//
  
// cộng 2 số
function cong($a, $b){
    // Các lệnh ..
}
  
// cộng 2 số
function tru($a, $b){
    // Các lệnh ..
}
  
// cộng 2 số
function nhan($a, $b){
    // Các lệnh ..
}
  
// cộng 2 số
function chia($a, $b){
    // Các lệnh ..
}
File nhanvien.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//------------------//
// FILE nhanvien.php --//
//------------------//
  
// Gọi module maths để xử lý tính toán
require ('maths.php');
  
// Thêm nhân viên
function them_nv()
{
    // Các lệnh ..
}
  
// Xóa nhân viên
function xoa_nv()
{
    // Các lệnh ..
}
  
// Sửa nhân viên
function edit_nv()
{
    // Các lệnh ..
}
  
// tính lương nhân viên
function luong_nv()
{
    // Các lệnh ..
}
File chuongtrinhchinh.php
1
2
3
4
5
6
7
8
// Gọi module nhanvien để thực hiện các thao tác của nhân viên
require 'nhanvien.php';
  
// Các thao tác
xoa_nv();
them_nv();
edit_nv();
luong_nv();
Ưu điểm:
  • Xây dựng được các chương trình lớn.- Code rõ ràng, dễ quản lý, bào trì và nâng cấp.
  • Phân theo khối nên mạch lạc
Nhước điểm:
  • Tuy phân theo khối nhưng dữ liệu không có sự gắn kết với nhau
  • Dữ liệu khởi tạo không bị huy sau khi gọi hàm

XÂY DỰNG CHƯƠNG TRÌNH THEO DÕI THÔNG TIN RA VÀO LỚP CỦA GIẢNG VIÊN

XÂY DỰNG CHƯƠNG TRÌNH THEO DÕI THÔNG TIN RA VÀO LỚP CỦA GIẢNG VIÊN

Việc đề xuất đưa ứng dụng của CNTT vào hỗ trợ trong các công việc hàng ngày ở các cơ quan nói chung và trường ĐHDL HP nói riêng hiện nay là rất cần thiết; việc cần phải đưa toàn bộ số liệu theo dõi thông tin ra vào lớp hàng ngày của giáo viên nhà trường, để từ đó xử lý, thống kê lập ra các báo cáo tổng hợp, chi tiết chính xác và nhanh chóng cho lãnh đạo nhà trường, các phòng ban, khoa, bộ môn thông qua một phần mềm hoàn thiện phù hợp với công nghệ hiện đại ngày nay là rất cần thiết. Phần mềm chương trình với việc sử dụng SQL Server 2005/2008 để tạo CSDL lưu trữ dữ liệu hàng ngày, dùng VB.NET để lập trình đã đáp ứng được hoàn toàn các yêu cầu công việc hiện tại đề ra và đã được đưa vào sử dụng ngay tại Ban Thanh tra GD nhà trường bắt đầu từ học kỳ 1 năm học 2011 - 2012 đã mang lại hiệu quả thiết thực.
1. Giới thiệu
Ngày nay với sự phát triển mạnh mẽ của Công nghệ thông tin (CNTT) và những lợi ích của CNTTmang lại trong đời sống xã hội hiện nay không thể phủ nhận. Đặc biệt việc đưa ứng dụng CNTT vào trong các công việc hàng ngày để trợ giúp một phần công việc cho các cán bộ nhân viên phòng ban hiện nay là rất cần thiết. Hiện nay trường ĐHDL HP đang chuyển sang mô hình đào tạo theo chế tín chỉ, bởi vậy với số lượng sinh viên nhiều thì mỗi học kỳ trong năm học số lượng lớp môn học rất lớn (khoảng gần 500 lớp môn học mỗi kỳ). Việc theo dõi thông tin giờ giấc ra vào lớp hàng ngày của giảng viên là rất cần thiết. Hàng ngày cán bộ Ban thanh tra GD phải thường xuyên theo dõi chi tiết việc thực hiện giờ giấc ra vào lớp của giảng viên ở các lớp (ra sớm, vào muộn, nghỉ dạy, …) để từ đó cuối mỗi ngày, mỗi tuần, mỗi tháng và cuối kỳ lập ra các báo cáo chi tiết để báo cáo lãnh đạo nhà trường, gửi các Bộ môn, các Khoa liên quan để biết được tình hình ra vào lớp giảng dạy hàng ngày của giảng viên đơn vị mình để góp ý điều chỉnh kịp thời. Hiện tại ban Thanh tra GD nhà trường vẫn thực hiện công việc này bằng phương pháp thủ công chủ yếu trên sổ sách giấy tờ (có sử dụng excel hỗ trợ). Tuy nhiên các báo cáo tổng hợp số liệu thống kê theo các tiêu chí đặt ra, tổng hợp để đưa ra chi tiết theo từng giáo viên cụ thể, từng đơn vị và các báo cáo khác vẫn chưa thực hiện được. Điều này dẫn đến một số bất cập về thời gian (mất nhiều thời gian, xử lý chậm) và độ chính xác trong công tác tổng hợp, báo cáo. Kết thúc mỗi học kỳ phải lập ra báo cáo tổng hợp về công tác giảng dạy trong kỳ của giảng viên (cơ hữu, thỉnh giảng ở HP và thỉnh giảng ở HN). Hiện tại công việc này được thực hiện tương đối khó khăn.
Ø  Bởi vậy việc cần có chương trình phần mềm để lưu trữ dữ liệu hàng ngày, từ đó xử lý để lập ra các báo cáo cho các công việc trên theo các yêu cầu nghiệp vụ đề ra được nhanh chóng, chính xác là rất cần thiết hiện nay với Nhà trường.
2. Một số yêu cầu của hệ thống

Phần mềm cần phải đảm bảo được các yêu cầu sau:
Ø  Phải sử dụng công nghệ lập trình trên môi trường .NET và dữ liệu được lưu trữ bởi SQL Server 2005/2008 để đảm bảo quá trình cập nhật dữ liệu cùng một lúc ở nhiều người dùng khác nhau qua mạng.
Ø  Tránh được sự xung đột khi nhiều máy client cập nhật dữ liệu đồng thời.
Ø  Hỗ trợ người dùng kiểm soát dữ liệu nhập vào.
Ø  Xử lý dữ liệu chính xác, nhanh chóng, đảm bảo được các yêu cầu công việc đề ra
Ø  Chương trình dễ sử dụng, thân thiện với người dùng.
3.  Phân tích và thiết kế hệ thống
       3.1.  Biểu đồ ngữ cảnh



4.  Kết quả thực nghiệm
Chương trình được cài đặt bởi ngôn ngữ VB.NET trong Visual Studio 2005 trên nền FrameWork.NET dạng Windows Form, CSDL được tạo lưu trữ bởi SQL Server 2005; đã được chạy với toàn bộ dữ liệu đầu vào là dữ liệu thực tế của trường Đại học Dân lập Hải Phòng, với đầy đủ chức năng đã đáp ứng được toàn bộ các yêu cầu công việc thực tế đề ra. Dưới đây là một số giao diện chính của chương trình: