Các đối tượng miền thông thường có các thuộc tính có thể được biểu thị bằng một loại dựng sẵn nhưng có các giá trị hợp lệ là tập hợp con của các giá trị có thể được biểu thị bằng loại đó.
Trong các trường hợp này, giá trị có thể được lưu trữ bằng cách sử dụng loại tích hợp nhưng cần phải đảm bảo các giá trị luôn được xác thực tại điểm nhập, nếu không chúng tôi có thể sẽ làm việc với giá trị không hợp lệ.
Một cách để giải quyết điều này là lưu trữ giá trị dưới dạng một tùy chỉnh struct
có một private readonly
trường sao lưu duy nhất của loại tích hợp và hàm tạo của nó xác nhận giá trị được cung cấp. Sau đó chúng ta có thể luôn chắc chắn chỉ sử dụng các giá trị được xác thực bằng cách sử dụng struct
loại này .
Chúng tôi cũng có thể cung cấp các toán tử truyền từ và đến loại tích hợp bên dưới để các giá trị có thể nhập và thoát liền mạch làm loại bên dưới.
Lấy ví dụ về một tình huống trong đó chúng ta cần thể hiện tên của một đối tượng miền và các giá trị hợp lệ là bất kỳ chuỗi nào có độ dài từ 1 đến 255 ký tự. Chúng ta có thể biểu diễn điều này bằng cách sử dụng cấu trúc sau:
public struct ValidatedName : IEquatable<ValidatedName>
{
private readonly string _value;
private ValidatedName(string name)
{
_value = name;
}
public static bool IsValid(string name)
{
return !String.IsNullOrEmpty(name) && name.Length <= 255;
}
public bool Equals(ValidatedName other)
{
return _value == other._value;
}
public override bool Equals(object obj)
{
if (obj is ValidatedName)
{
return Equals((ValidatedName)obj);
}
return false;
}
public static implicit operator string(ValidatedName x)
{
return x.ToString();
}
public static explicit operator ValidatedName(string x)
{
if (IsValid(x))
{
return new ValidatedName(x);
}
throw new InvalidCastException();
}
public static bool operator ==(ValidatedName x, ValidatedName y)
{
return x.Equals(y);
}
public static bool operator !=(ValidatedName x, ValidatedName y)
{
return !x.Equals(y);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return _value;
}
}
Ví dụ chương trình các to- string
dàn diễn viên như implicit
thế này không bao giờ có thể thất bại nhưng từ- string
cast như explicit
vì điều này sẽ ném cho các giá trị không hợp lệ, nhưng tất nhiên những cả hai có thể là một trong hai implicit
hoặc explicit
.
Cũng lưu ý rằng người ta chỉ có thể khởi tạo cấu trúc này bằng cách truyền từ string
, nhưng người ta có thể kiểm tra xem một diễn viên như vậy sẽ thất bại trước khi sử dụng IsValid
static
phương thức này.
Đây dường như là một mô hình tốt để thực thi xác thực các giá trị miền có thể được biểu thị bằng các loại đơn giản, nhưng tôi không thấy nó được sử dụng thường xuyên hoặc được đề xuất và tôi quan tâm đến lý do tại sao.
Vì vậy, câu hỏi của tôi là: bạn thấy ưu điểm và nhược điểm của việc sử dụng mẫu này là gì và tại sao?
Nếu bạn cảm thấy rằng đây là một mô hình xấu, tôi muốn hiểu tại sao và những gì bạn cảm thấy là sự thay thế tốt nhất.
NB Ban đầu tôi đã hỏi câu hỏi này trên Stack Overflow nhưng nó được đặt dưới dạng chủ yếu dựa trên ý kiến (chủ quan trớ trêu thay) - hy vọng nó có thể tận hưởng thành công hơn ở đây.
Trên đây là văn bản gốc, bên dưới một vài suy nghĩ, một phần để đáp lại câu trả lời nhận được ở đó trước khi nó bị giữ lại:
- Một trong những điểm chính được đưa ra bởi các câu trả lời là xung quanh số lượng mã tấm nồi hơi cần thiết cho mẫu trên, đặc biệt là khi nhiều loại như vậy được yêu cầu. Tuy nhiên, để bảo vệ mẫu, điều này có thể được tự động hóa phần lớn bằng cách sử dụng các mẫu và thực sự với tôi nó dường như không quá tệ, nhưng đó chỉ là ý kiến của tôi.
- Từ quan điểm khái niệm, có vẻ không lạ khi làm việc với một ngôn ngữ được gõ mạnh như C # để chỉ áp dụng nguyên tắc gõ mạnh cho các giá trị tổng hợp, thay vì mở rộng nó thành các giá trị có thể được biểu thị bằng một thể hiện của loại tích hợp?