
我的项目/计划将跟踪建筑项目图纸的变化,并在更改图纸时向人们发送通知.
将有许多建筑项目(工地),每个建筑项目中都会有很多图纸.每个图纸都会有一些修改(当它们被更改时,会创建一个新版本).
这是我的项目类
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代码中,父类几乎总是拥有对子代的引用.孩子们通常不需要引用他们的父母,因为你访问孩子的唯一方法是已经拥有父母.
总结以上是内存溢出为你收集整理的c# – 循环引用 – 架构问题全部内容,希望文章能够帮你解决c# – 循环引用 – 架构问题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)