616
Chương 16: Các giao diện và mẫu thông dụng
Dễ dàng hiện thực một bản sao cạn—sử dụng phương thức
MemberwiseClone
vừa được mô tả.
Tuy nhiên, một bản sao sâu thường là cái mà lập trình viên mong đợi khi lần đầu tiên sao một
đối tượng—nhưng hiếm khi là cái họ lấy. Điều này đặc biệt đúng đối với các lớp tập hợp
trong không gian tên
System.Collections
, tất cả đều hiện thực bản sao cạn trong các phương
thức
Clone
của chúng. Mặc dù sẽ có ích nếu các tập hợp này hiện thực bản sao sâu, có hai lý
do chính để các kiểu (đặc biệt là các lớp tập hợp) không hiện thực bản sao sâu:
•
Việc tạo bản sao của một đồ thị đối tượng lớn sẽ tốn nhiều bộ nhớ và thời gian xử lý.
•
Các tập hợp thông thường có thể chứa các đồ thị đối tượng sâu và rộng, bao gồm bất kỳ
kiểu đối tượng nào. Việc tạo một hiện thực bản sao sâu để phục vụ nhiều thứ như thế là
không khả thi vì một số đối tượng trong tập hợp có thể không phải là khả-sao-chép, và
một số khác có thể chứa các tham chiếu vòng, khiến quá trình sao chép trở thành một
vòng lặp vô tận.
Đối với các tập hợp kiểu mạnh, trong đó bản chất của các phần tử được hiểu và được kiểm
soát thì một bản sao sâu có thể là một tính năng rất hữu ích. Ví dụ,
System.Xml.XmlNode
hiện
thực một bản sao sâu trong phương thức
Clone
, điều này cho phép bạn tạo đúng bản sao của
toàn bộ hệ thống phân cấp đối tượng XML chỉ với một lệnh đơn.
Nếu cần sao một đối tượng không hiện thực
ICloneable
nhưng lại là khả-tuần-tự-
hóa, bạn có thể tuần tự hóa rồi giải tuần tự hóa đối tượng đó để có được cùng kết
quả như khi sao chép. Tuy nhiên, quá trình tuần tự hóa có thể không tuần tự hóa
tất cả các thành viên dữ liệu (như đã được thảo luận trong mục 16.1). Cũng vậy,
nếu tạo một kiểu khả-tuần-tự-hóa tùy biến, bạn có thể sử dụng quá trình tuần tự
hóa vừa được mô tả để thực hiện một bản sao sâu bên trong phương thức
ICloneable.Clone
. Để sao một đối tượng khả-tuần-tự-hóa, bạn hãy sử dụng lớp
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
để tuần tự
hóa đối tượng này thành một đối tượng
System.IO.MemoryStream
, và rồi giải tuần
tự hóa đối tượng này từ
System.IO.MemoryStream
.
Lớp
Team
dưới đây hiện thực phương thức
Clone
thực hiện một bản sao sâu. Lớp
Team
chứa
một tập hợp các đối tượng
Employe
mô tả một nhóm người. Khi bạn gọi phương thức
Clone
của một đối tượng
Team
, phương thức này sẽ tạo bản sao của mỗi đối tượng
Employee
và thêm
nó vào đối tượng
Team
được sao. Lớp
Team
cung cấp một phương thức khởi dựng
private
để
đơn giản hóa mã lệnh trong phương thức
Clone
(sử dụng phương thức khởi dựng là cách
thông thường để đơn giản hóa quá trình sao chép).
using System;
using System.Collections;
public class Team : ICloneable {
public ArrayList TeamMembers = new ArrayList();
public Team() {