Có thể tổng hợp bất biến bao gồm quy tắc dựa trên thông tin từ nơi khác không?
Tổng hợp luôn có thể sử dụng thông tin ở trạng thái của riêng mình và đối số rằng số commands của họ sẽ nhận được.
Một người nào đó sử dụng để truy cập các dịch vụ ứng dụng thông qua người độc thân, người định vị dịch vụ vv, nhưng IMO, đó là mùi của các ứng dụng được kết hợp chặt chẽ. Họ quên rằng các đối số của phương pháp là các bộ phận phụ thuộc hiệu quả! :-)
Trong DDD có thể tổng hợp bất biến bao gồm quy tắc dựa trên thông tin trong tổng hợp khác?
No.
Trừ khi tổng hợp thứ hai được cung cấp qua đối số lệnh, tất nhiên.
CẢNH BÁO! ! !
Tôi đã một thực thể gọi là tài sản (thiết bị) ...
... (và a) tổng hợp thứ hai gọi là AssetType ...
Lần cuối cùng mà tôi đã phải đối phó với một cấu trúc tương tự, đó là một cơn đau.
Rất có thể bạn đang chọn trừu tượng sai.
tôi đã gặp lỗi bất biến của mình chưa?
Có lẽ ... Bạn đã yêu cầu chuyên gia tên miền ? Có phải anh ta nói về "TagTypes" không?
You should never abstract on your own.
Đối tượng thuộc loại X
giữ tham chiếu đến phiên bản X-Type
hầu như luôn có mùi trừu tượng, với hy vọng tái sử dụng, làm cho mô hình cứng nhắc và không linh hoạt trong quá trình phát triển kinh doanh.
ĐÁP
Nếu (và chỉ nếu) chuyên gia miền thực sự mô tả mô hình trong các điều khoản, một cách tiếp cận có thể là như sau:
- bạn có thể tạo một lớp
AssetType
với phương pháp nhà máy biến một số điện thoại IEnumerable<Tag>
thành TagSet
and throws hoặc MissingMandatoryTagException
hoặc UnexpectedTagException
nếu một số thẻ bị thiếu hoặc không mong muốn.
- trong lớp
Asset
, một lệnh RegisterTags
sẽ chấp nhận một AssetType
và một IEnumerable<Tag>
, ném MissingMandatoryTagException
và WrongAssetTypeException
(lưu ý tầm quan trọng đang ngoại lệ để đảm bảo bất biến).
chỉnh sửa
một cái gì đó như thế này, nhưng nhiều hơn nữa tài liệu:
public class AssetType
{
private readonly Dictionary<TagType, bool> _tagTypes = new Dictionary<TagType, bool>();
public AssetType(AssetTypeName name)
{
// validation here...
Name = name;
}
/// <summary>
/// Enable a tag type to be assigned to asset of this type.
/// </summary>
/// <param name="type"></param>
public void EnableTagType(TagType type)
{
// validation here...
_tagTypes[type] = false;
}
/// <summary>
/// Requires that a tag type is defined for any asset of this type.
/// </summary>
/// <param name="type"></param>
public void RequireTagType(TagType type)
{
// validation here...
_tagTypes[type] = false;
}
public AssetTypeName Name { get; private set; }
/// <summary>
/// Builds the tag set.
/// </summary>
/// <param name="tags">The tags.</param>
/// <returns>A set of tags for the current asset type.</returns>
/// <exception cref="ArgumentNullException"><paramref name="tags"/> is <c>null</c> or empty.</exception>
/// <exception cref="MissingMandatoryTagException">At least one of tags required
/// by the current asset type is missing in <paramref name="tags"/>.</exception>
/// <exception cref="UnexpectedTagException">At least one of the <paramref name="tags"/>
/// is not allowed for the current asset type.</exception>
/// <seealso cref="RequireTagType"/>
public TagSet BuildTagSet(IEnumerable<Tag> tags)
{
if (null == tags || tags.Count() == 0)
throw new ArgumentNullException("tags");
TagSet tagSet = new TagSet();
foreach (Tag tag in tags)
{
if(!_tagTypes.ContainsKey(tag.Key))
{
string message = string.Format("Cannot use tag {0} in asset type {1}.", tag.Key, Name);
throw new UnexpectedTagException("tags", tag.Key, message);
}
tagSet.Add(tag);
}
foreach (TagType tagType in _tagTypes.Where(kvp => kvp.Value == true).Select(kvp => kvp.Key))
{
if(!tagSet.Any(t => t.Key.Equals(tagType)))
{
string message = string.Format("You must provide the tag {0} to asset of type {1}.", tagType, Name);
throw new MissingMandatoryTagException("tags", tagType, message);
}
}
return tagSet;
}
}
public class Asset
{
public Asset(AssetName name, AssetTypeName type)
{
// validation here...
Name = name;
Type = type;
}
public TagSet Tags { get; private set; }
public AssetName Name { get; private set; }
public AssetTypeName Type { get; private set; }
/// <summary>
/// Registers the tags.
/// </summary>
/// <param name="tagType">Type of the tag.</param>
/// <param name="tags">The tags.</param>
/// <exception cref="ArgumentNullException"><paramref name="tagType"/> is <c>null</c> or
/// <paramref name="tags"/> is either <c>null</c> or empty.</exception>
/// <exception cref="WrongAssetTypeException"><paramref name="tagType"/> does not match
/// the <see cref="Type"/> of the current asset.</exception>
/// <exception cref="MissingMandatoryTagException">At least one of tags required
/// by the current asset type is missing in <paramref name="tags"/>.</exception>
/// <exception cref="UnexpectedTagException">At least one of the <paramref name="tags"/>
/// is not allowed for the current asset type.</exception>
public void RegisterTags(AssetType tagType, IEnumerable<Tag> tags)
{
if (null == tagType) throw new ArgumentNullException("tagType");
if (!tagType.Name.Equals(Type))
{
string message = string.Format("The asset {0} has type {1}, thus it can not handle tags defined for assets of type {2}.", Name, Type, tagType.Name);
throw new WrongAssetTypeException("tagType", tagType, message);
}
Tags = tagType.BuildTagSet(tags);
}
}
Cảm ơn bạn đã trả lời. Tôi nghĩ sự nhất quán cuối cùng là câu trả lời như bạn đã nói. Mặc dù @GiacomoTesio đã cung cấp trợ giúp tuyệt vời cũng – MJM
Tôi cũng chỉ ra cho những người khác đọc điều này, rằng bản năng suy ra điều kiện là tất cả quá dễ dàng. Như chúng tôi đã phát hiện ra các sự kiện thực tế là tài sản được tạo ra từ AssteTypes nhưng sau đó, nhiều hay ít, rời rạc khỏi Type gốc. Tham chiếu có thể được thực hiện trở lại tại bất kỳ thời điểm nào đối với đặc tả ban đầu của Nội dung và kết quả được cập nhật theo nghĩa, nhưng hành động này được gọi bởi người gọi chứ không phải là tác dụng phụ của việc lưu Loại gốc. Nhận thức này đã giúp rất nhiều. – MJM