c# – 循环引用 – 架构问题
这可能是一个非常初学的问题,但我已经搜索了很多主题并且无法找到相同的情况,尽管我确信这种情况一直都在发生.
我的项目/计划将跟踪建筑项目图纸的变化,并在更改图纸时向人们发送通知. 将有许多建筑项目(工地),每个建筑项目中都会有很多图纸.每个图纸都会有一些修改(当它们被更改时,会创建一个新版本). 这是我的项目类 public class Project { private readonly List<Drawing> _drawings = new List<Drawing>(30); private readonly List<Person> _autoRecepients = new List<Person>(30); public int ID { get; private set; } public string ProjectNumber { get; private set; } public string Name { get; private set; } public bool Archived { get; private set; } public List<Person> AutoRecepients { get { return _autoRecepients; } } public Project(int id,string projectNumber,string name) { if (id < 1) { id = -1; } ID = id; ProjectNumber = projectNumber; Name = name; } public bool AddDrawing(Drawing drawing) { if (drawing == null) return false; if (_drawings.Contains(drawing)) { return true; } _drawings.Add(drawing); return _drawings.Contains(drawing); } public void Archive() { Archived = true; } public bool DeleteDrawing(Drawing drawing) { return _drawings.Remove(drawing); } public IEnumerable<Drawing> ListDrawings() { return _drawings.AsReadOnly(); } public override string ToString() { return string.Format("{0} {1}",ProjectNumber,Name); } } 这是我的绘画课 public class Drawing : IDrawing { private List<IRevision> _revisions = new List<IRevision>(5); private List<IssueRecord> _issueRecords = new List<IssueRecord>(30); private IRevision _currentRevision; public int ID { get; private set; } public string Name { get; private set; } public string Description { get; set; } public Project Project { get; private set; } public IRevision CurrentRevision { get { return _currentRevision; } } public Drawing(int id,string name,string description,Project project) { // To be implemented } /// <summary> /// Automatically issue the current revision to all Auto Recepients /// </summary> public void AutoIssue(DateTime date) { AutoIssue(date,_currentRevision); } /// <summary> /// Automatically issue a particular revision to all Auto Recepients /// </summary> public void AutoIssue(DateTime date,IRevision revision) { } public void IssueTo(Person person,DateTime date,IRevision revision) { _issueRecords.Add(new IssueRecord(date,this,revision,person)); throw new NotImplementedException(); } public void IssueTo(Person person,DateTime date) { IssueTo(person,date,_currentRevision); } public void IssueTo(IEnumerable<Person> people,DateTime date) { IssueTo(people,_currentRevision); } public void IssueTo(IEnumerable<Person> people,IRevision revision) { foreach (var person in people) { IssueTo(person,revision); } } public void Rename(string name) { if (string.IsNullOrWhiteSpace(name)) { return; } Name = name; } public void Revise(IRevision revision) { if (revision.Name == null ) return; _revisions.Add(revision); _currentRevision = revision; } public struct IssueRecord { public int ID { get; private set; } public DateTime Date { get; private set; } public IDrawing Drawing { get; private set; } public IRevision Revision { get; private set; } public Person Person { get; private set; } public IssueRecord(int id,IDrawing drawing,IRevision revision,Person person) { if (id < 1) { id = -1; } ID = id; Date = date; Drawing = drawing; Revision = revision; Person = person; } } } 这是Revision结构 public struct Revision : IRevision { public int ID { get; private set; } public string Name { get; } public DateTime Date { get; set; } public IDrawing Drawing { get; } public IDrawingFile DrawingFile { get; private set; } public Revision(int id,IDrawingFile drawingFile) { if (name == null) { throw new ArgumentNullException("name","Cannot create a revision with a null name"); } if (drawing == null) { throw new ArgumentNullException("drawing","Cannot create a revision with a null drawing"); } if (id < 1) { id = -1; } ID = id; Name = name; Drawing = drawing; Date = date; DrawingFile = drawingFile; } public Revision(string name,IDrawingFile drawingFile) : this(-1,name,drawing,drawingFile) { } public Revision(string name,IDrawing drawing) : this(-1,DateTime.Today,null) { } public void ChangeID(int id) { if (id < 1) { id = -1; } ID = id; } public void SetDrawingFile(IDrawingFile drawingFile) { DrawingFile = drawingFile; } } 我的问题是在绘图类中的项目引用和修订结构中的绘图引用. 绘图对象似乎有必要知道它属于哪个项目,这样如果我正在使用单个绘图对象,我就可以知道它们属于哪个项目. 类似地,每个修订版本基本上由图纸“拥有”或者是图纸的一部分.没有绘图,修订没有意义,所以它需要引用它所属的绘图? 任何建议将不胜感激. 解决方法
你所拥有的不仅仅是循环引用,而是两个例子
可以从两端导航的亲子关系. 是的,这是正常的,可接受的,不是代码味道.是的,一些序列化工具需要您提示.例如Newtonsoft.Json需要ReferenceLoopHandling.Ignore设置. 作为一个概念的导航性并不总是在OO设计中被讨论,这是不幸的,因为它只是你想要的概念. (这是UML中的明确术语). 您通常不需要从两端进行导航.父子关系通常仅从父对子编码.这很常见.例如,invoiceline类很少需要其父发票的显式字段,因为大多数应用程序仅在检索父发票后查看该行. 所以设计决定不是, “没有绘画,修改是否有意义?” 但 “我是否需要找到仅给出修订版的图纸?” 我的猜测是你的修订就像发票行,而不需要导航到他们的父母.图纸的答案< - >项目对我来说并不明显. (这是关于您的域名的分析问题,而不是代码式问题). 这是OO代码与SQL之间的显着差异.在SQL数据库中,它必须是包含对其父图形ID的引用的修订表.在OO代码中,父类几乎总是拥有对子代的引用.孩子们通常不需要引用他们的父母,因为你访问孩子的唯一方法是已经拥有父母. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |