我正在通过开发C#音乐管理软件来学习OOP。到目前为止,我已经列出了不同类和对象的交互,如此类图http://img811.imageshack.us/img811/7624/classdiagramh.png
所示然而,我对于让我的设计变得非常困难,因为我发现了无数可能的事情,但我不想最终设计糟糕。我遇到的主要问题是确保我在不同对象之间强制执行数据完整性(据我所知,我认为在OOP中,就像在数据库设计中一样,有一种方法可以提供准确性,一致性和可靠性数据存储在不同的对象中,因为它是在数据库设计中完成的(例如使用外键约束)。例如,在我的应用程序中,我有Artist,Song和Album对象应该一起交互。我不想要例如,错误地将一首歌与错误的专辑相关联。我被告知我应该做类似的事情:
class Album
{
public String Name{ get; set;}
List<Track> tracks;
public void AddTrack(Track t)
{
tracks.Add(t);
t.Album = this;
}
}
class Track
{
public Album Album{ get; set;}
public String AlbumName
{
get{ return this.Album.Name}
}
public String ArtistName{ get; set}
}
然而,这对我不起作用。有人可以建议我如何才能真正做到这一点。具体来说,我如何添加一首带有标题,专辑和艺术家的新歌,并确保如果因某些奇怪的原因更改了专辑的名称,所有曲目仍将返回正确的专辑名称,因为它们是从专辑本身获取数据?
此外,有人可以提出更好的设计。我应该使用继承还是任何多态来使我的设计健壮?
答案 0 :(得分:0)
在数据库设计中,您必须根据业务需求做出选择。手段: 你必须问自己有关可能的星座的问题 - 来自同一位艺术家的CD上的所有歌曲?不 - &gt;轨道上的艺术家字段,是 - &gt;专辑上的艺术家字段 - 当你知道一首曲目或者只是特定专辑的所有曲目时,你是否必须能够获得专辑? - ......
您正在从Track对象引用引用的Album的名称的方式是正确的。更重要的是:他们确实返回了专辑名称,但只返回了专辑在GET时刻的名称。 因此,如果您将AlbumName属性分配给可视控件,或者更改相册名称时不会自动更新的任何内容。
如果那不是您想要听到的内容,请更具体。
答案 1 :(得分:0)
其实你没有做协会。
在面向对象的编程中,您可以关联对象而不是“键”。没有“外键”的概念。
如果对象B具有父A,而A具有唯一标识符,则不会通过设置此唯一标识符来关联B的父对象,而是对象本身:
B有父A :
public class A { public Guid ID { get; set; } }
public class B { public A Parent { get; set; } }
A someA = new A();
B someB = new B();
someB.Parent = someA;
以这种方式工作,因为“A的实例”可能与许多其他对象相关联,从任何引用中更改同一对象,将导致修改该对象。
如何实现完整性约束?有一些设计模式,但最常见的一种是规范。
这是创建一个通用接口“ISpecification”,它有一个可以称为“Check”的方法,它接受一个参数 - 该对象来检查规范 - 。在实现中,此方法将检查某个对象是否符合某些规范。
public interface ISpecification { bool Check(object some); }
public class Person { public string Name { get; set; } }
public class PersonSpecification : ISpecification
{
public bool Check(object some)
{
// Checks that some person won't be null and his/her name isn't null or empty
return some != null && !string.IsNullOrEmpty(((Person)some).Name);
}
}
这是如何实现业务规则和/或约束的非常简单和通用的示例。
有很多框架可以帮助你在这方面:
Microsoft Patterns&amp;实践验证阻止:http://msdn.microsoft.com/en-us/library/ff648831.aspx
NHibernate Validator:http://nhforge.org/wikis/validator/nhibernate-validator-1-0-0-documentation.aspx(它是NHibernate项目的一部分,但它可以在没有NHibernate的情况下单独使用)。
在某些项目中,我集成了NHibernate Validator和其他项目,这是一种基于规范模式的自定义解决方案,但其方式比样本更复杂,更灵活。
关于规格模式: