像《海盗守则》一样,SRP不仅仅是一条准则,而是一条准则,而且措辞也不是特别好。大多数开发人员已经接受了Martin Fowler(在Refactoring中)和Robert Martin(在Clean Code中)的重新定义,这表明类应该只具有一个改变的理由(而不是一种责任)。
这是一个很好的,牢固的(对双关语表示敬意的)准则,但是挂掉它几乎和忽略它一样危险。
如果你可以添加一个张贴标签和反之亦然,你没有破坏单责任原则。两者仍然只有一个更改的理由-如果该对象的结构发生更改。更改任何一个的结构都不会更改将其添加到另一个结构的方式,因此您不会在其中添加新的“责任”。
您的最终决定实际上应该由前端所需的功能决定。在某个时候可能需要将标签添加到帖子中,因此请执行以下操作:
// C-style-language pseudo-code
class Post {
string _title;
string _content;
Date _date;
List<Tag> _tags;
Post(string title, string content) {
_title = title;
_content = content;
_date = Now;
_tags = new List<Tag>();
}
Tag[] getTags() {
return _tags.toArray();
}
void addTag(Tag tag) {
if (_tags.contains(tag)) {
throw "Cannot add tag twice";
}
_tags.Add(tag);
tag.referencePost(this);
}
// more stuff here, obviously
}
class Tag {
string _name;
List<Post> _posts;
Tag(string name) {
_name = name;
}
Post[] getPosts() {
return _posts.toArray();
}
void referencePost(Post post) {
if (!post.getTags().contains(this) || _posts.contains(post)) {
throw "Only reference a post by calling Post.addTag()";
}
_posts.Add(post);
}
// more stuff here too
}
以后,如果您还需要将Posts添加到Tag,只需将addPost方法添加到Tag类,并将referenceTag方法添加到Post类。显然,我用不同的方式命名了它们,以便您不会通过从addPost调用addTag和从addTag调用addPost意外导致堆栈溢出。