Chương 16 : Các giao din và mu thông dng
Chương này trình bày cách hin thc các mu (pattern) s được s dng thường xuyên
trong quá trình phát trin các ng dng Microsoft .NET Framework. Mt s mu được
chun hóa bng các giao din được định nghĩa trong thư vin lp .NET Framework. Mt
s khác thì ít cng nhc hơn, nhưng vn yêu cu bn thc hin các cách tiếp cn c th để
thiết kế và hin thc các kiu ca bn. Các mc trong chương này mô t cách:
To các kiu kh-tun-t-hóa để bn có th d dàng lưu tr vào đĩa, gi qua mng,
hoc truyn bng tr qua các biên min ng dng (mc 16.1).
Cung cp mt cơ chế dùng để to bn sao đầy đủ và chính xác ca đối tượng (mc
16.2).
Hin thc các kiu sao cho d dàng so sánh và sp xếp (mc 16.3).
H tr vic lit kê các phn t trong các tp hp tùy biến (mc 16.4).
Bo đảm rng mt kiu có s dng các tài nguyên không-được-qun-lý s gii
phóng các tài nguyên đó khi không còn cn đến chúng na (mc 16.5).
Hin th dng chui ca các đối tượng biến đổi da trên format specifier (mc 16.6).
Hin thc các kiu đối s s kin và ngoi l tùy biến (bn s thường xuyên s dng
chúng trong quá trình phát trin ng dng) (mc 16.7 và 16.8).
Hin thc các mu thiết kế thông dng SingletonObserver bng các tính năng có
sn ca C# và thư vin lp .NET Framework (mc 16.9 và 16.10).
1.1 Hin thc kiu kh-tun-t-hóa (serializable type)
V
V
Bn cn hin thc mt kiu tùy biến kh-tun-t-hóa, cho phép bn:
Lưu tr các th hin ca kiu vào kho lưu tr (file hay cơ s d liu).
Chuyn các th hin ca kiu qua mng.
Truyn các th hin ca kiu “bng tr” qua các biên min ng dng.
#
#
Đối vi vic tun t hóa các kiu đơn gin, hãy áp dng đặc tính
System.SerializableAttribute vào khai báo kiu. Đối vi các kiu phc tp hơn,
hoc để kim soát ni dung và cu trúc ca d liu được-tun-t-hóa, hãy hin
thc giao din System.Runtime.Serialization.ISerializable.
Mc 2.12 đã trình bày cách tun t hóa và gii tun t hóa mt đối tượng bng các lp
formatter (được cp cùng vi thư vin lp .NET Framework). Tuy nhiên, theo mc định
thì các kiu không là kh-tun-t-hóa. Để hin thc mt kiu tùy biến là kh-tun-t-hóa,
bn phi áp dng đặc tính SerializableAttribute vào khai báo kiu. Khi tt c các trường
d liu trong kiu đều là kh-tun-t-hóa, vic áp dng SerializableAttribute là tt c
nhng gì cn làm để khiến cho kiu tùy biến ca bn là kh-tun-t-hóa. Nếu bn hin
thc mt lp tùy biến dn xut t mt lp cơ s, lp cơ s cũng phi là kh-tun-t-hóa.
Mi lp formatter cha logic cn thiết để tun t hóa các kiu được gn vi đặc tính
SerializableAttribute và s tun t hóa tt c các trường public, protected, và private.
Đon mã dưới đây trình bày các khai báo kiu và khai báo trường ca mt lp kh-tun-
t-hóa có tên là Employee.
using System;
[Serializable]
public class Employee {
private string name;
private int age;
private string address;
§
}
# Các lp dn xut t mt kiu kh-tun-t-hóa không tha kế đặc tính
SerializableAttribute. Để khiến cho các kiu dn xut là kh-tun-t-hóa, bn
phi khai báo chúng là kh-tun-t-hóa bng cách áp dng đặc tính
SerializableAttribute.
Bn có th ngăn vic tun t hóa mt trường nào đó bng cách áp dng đặc tính
System.NonSerializedAttribute cho trường này. Bn nên ngăn vic tun t hóa đối vi
các trường sau:
Cha các kiu d liu không-kh-tun-t-hóa.
Cha các giá tr có th không hp l khi đối tượng được gii tun t hóa, ví d: kết
ni cơ s d liu, địa ch b nh, ID ca tiu trình, và handle ca tài nguyên không-
được-qun-lý.
Cha các thông tin nhy cm hay riêng tư, ví d: mt khu, khóa mt hóa, và các chi
tiết riêng v người hay t chc.
Cha các d liu d dàng tái to hay thu ly được t các ngun khác—đặc bit khi
d liu ln.
Nếu ngăn vic tun t hóa mt s trường, bn phi hin thc kiu sao cho bù li vic
nhng d liu nào đó s không hin din khi mt đối tượng được gii tun t hóa. Đáng
tiếc, bn không th to hay thu ly các trường d liu b mt trong mt phương thc khi
dng vì formatter không gi phương thc khi dng trong quá trình gii tun t hóa đối
tượng. Gii pháp thông thường nht là hin thc mu “Lazy Initialization”, trong đó kiu
ca bn s to hay thu ly d liu ngay ln đầu tiên cn đến.
Đon mã dưới đây trình bày mt phiên bn đã được chnh sa ca lp Employee vi đặc
tính NonSerializedAttribute được áp dng cho trường address, nghĩa là formatter s
không tun t hóa giá tr ca trường này. Lp Employee hin thc các thuc tính công
khai dùng để truy xut các thành viên d liu riêng, là nơi thun tin để hin thc “Lazy
Initialization” cho trường address.
using System;
[Serializable]
public class Employee {
private string name;
private int age;
[NonSerialized]
private string address;
// Phương thc khi dng đơn gin.
public Employee(string name, int age, string address) {
this.name = name;
this.age = age;
this.address = address;
}
// Thuc tính công khai dùng để truy xut tên ca nhân viên.
public string Name {
get { return name; }
set { name = value; }
}
// Thuc tính công khai dùng để truy xut tui ca nhân viên.
public int Age {
get { return age; }
set { age = value; }
}
// Thuc tính công khai dùng để truy xut địa ch ca nhân viên.
// S dng "Lazy Initialization" để thiết lp địa ch
// đối tượng được-gii-tun-t-hóa s không có giá tr địa ch.
public string Address {
get {
if (address == null) {
// Np địa ch t kho lưu tr.
}
return address;
}
set {
address = value;
}
}
}
Đối vi phn ln các kiu tùy biến, vic s dng đặc tính SerializableAttribute và
NonSerializedAttribute s đáp ng đủ nhu cu tun t hóa ca bn. Nếu cn kim soát
quá trình tun t hóa, bn cn hin thc giao din ISerializable. Các lp formatter s
dng logic khác nhau khi tun t hóa và gii tun t hóa th hin ca các kiu có hin
thc ISerializable. Để hin thc đúng ISerializable, bn phi:
Khai báo rng kiu ca bn có hin thc giao din ISerializable.
Áp dng đặc tính SerializableAttribute vào khai báo kiu như va được mô t;
không s dng NonSerializedAttribute vì nó s không có tác dng.
Hin thc phương thc ISerializable.GetObjectData (được s dng trong quá trình
tun t hóa), phương thc này nhn các kiu đối s sau:
System.Runtime.Serialization.SerializationInfo
System.Runtime.Serialization.StreamingContext
Hin thc mt phương thc khi dng không công khai (được s dng trong quá
trình gii tun t hóa), phương thc này nhn cùng đối s như phương thc
GetObjectData. Nh rng, nếu bn có ý định dn xut mt s lp t lp kh-tun-t-
hóa thì phương thc khi dng này phi là protected.
Nếu bn to mt lp kh-tun-t-hóa t mt lp cơ s
cũng có hin thc
ISerializable, thì phương thc GetObjectData và phương thc khi dng (dùng để
gii tun t hóa) ca bn phi gi các phương thc tương đương trong lp cha.
Trong quá trình tun t hóa, formatter s gi phương thc GetObjectData và truyn cho
nó các tham chiếu SerializationInfo và StreamingContext.
Bn phi đổ d liu cn tun t hóa vào đối tượng SerializationInfo. Lp
SerializationInfo cung cp phương thc AddValue dùng để thêm d liu. Vi mi
ln gi AddValue, bn phi ch định tên d liu (tên này s được s dng trong quá
trình gii tun t hóa để thu ly d liu). Phương thc AddValue có đến 16 phiên
bn np chng, cho phép bn thêm nhiu kiu d liu khác nhau vào đối tượng
SerializationInfo.
Đối tượng StreamingContext cung cp các thông tin v ch định và đích ca d liu
được-tun-t-hóa, cho phép bn chn tun t hóa d liu nào. Ví d, bn có th cn
tun t hóa d liu riêng nếu nó được dành cho mt min ng dng khác trong cùng
tiến trình, nhưng không cn nếu d liu s được ghi ra file.
Trong quá trình gii tun t hóa, formatter s gi phương thc khi dng vic gii tun
t hóa, li truyn cho nó các tham chiếu SerializationInfo và StreamingContext.
Kiu ca bn phi trích d liu đã-được-tun-t-hóa t đối tượng SerializationInfo
bng mt trong các phương thc SerializationInfo.Get*, ví d: GetString, GetInt32,
hay GetBoolean.
Đối tượng StreamingContext cung cp các thông tin v ngun gc ca d liu đã-
được-tun-t-hóa, phn ánh logic mà bn đã hin thc cho vic tun t hóa.
# Trong quá trình tun t hóa chun, formatter không s dng kh năng ca đối
tượng StreamingContext để cho biết các chi tiết v ngun gc, đích, và ch
định ca d liu được-tun-t-hóa. Tuy nhiên, nếu mun thc hin quá trình
tun t hóa tùy biến, bn có th cu hình đối tượng StreamingContext ca
formatter trước khi bt đầu quá trình tun t hóa và gii tun t hóa. Tham
kho tài liu .NET Framework SDK để có thêm thông tin v lp
StreamingContext.
Ví d dưới đây trình bày phiên bn đã được chnh sa ca lp Employee, có hin thc
giao din ISerializable. Trong phiên bn này, lp Employee không tun t hóa trường
address nếu đối tượng StreamingContext ch định rng đích ca d liu được-tun-t-hóa
là file. Phương thc Main s gii thích vic tun t hóa và gii tun t hóa ca mt đối
tượng Employee.
using System;
using System.Runtime.Serialization;
[Serializable]
public class Employee : ISerializable {
private string name;
private int age;
private string address;
// Phương thc khi dng đơn gin.