c# – 循环引用 – 架构问题

c# – 循环引用 – 架构问题,第1张

概述这可能是一个非常初学的问题,但我已经搜索了很多主题并且无法找到相同的情况,尽管我确信这种情况一直都在发生. 我的项目/计划将跟踪建筑项目图纸的变化,并在更改图纸时向人们发送通知. 将有许多建筑项目(工地),每个建筑项目中都会有很多图纸.每个图纸都会有一些修改(当它们被更改时,会创建一个新版本). 这是我的项目类 public class Project{ private readonly 这可能是一个非常初学的问题,但我已经搜索了很多主题并且无法找到相同的情况,尽管我确信这种情况一直都在发生.

我的项目/计划将跟踪建筑项目图纸的变化,并在更改图纸时向人们发送通知.

将有许多建筑项目(工地),每个建筑项目中都会有很多图纸.每个图纸都会有一些修改(当它们被更改时,会创建一个新版本).

这是我的项目类

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# – 循环引用 – 架构问题所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1263000.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-08
下一篇2022-06-08

发表评论

登录后才能评论

评论列表(0条)

    保存