我有一系列对象,我已使用LINQ to SQL映射到数据库。表格高度标准化。我要抽象我的问题。我在数据库中实现了五个中心实体。然后,我有一系列其他对象,我想实现这五个实体中的一个或全部。
假设我正在实施一种体育课(想想运动队)。这五个实体是五大运动;棒球,篮球,足球,曲棍球,足球。我想为每个体育场明确实施一个课程。
这是一个例子,洋基体育场举办了棒球,曲棍球和足球比赛。我希望它实现这3个接口中的每一个。 StadiumBaseClass是我的抽象基类,它与我的数据库接口。 StadiumBaseClass实现了所有5个主要的运动界面。我不希望在所有可能的体育馆中使用相同的代码来实现IBaseball接口,我希望它在StadiumBaseClass中实现一次。
我这个例子,我只想实现3,这是最好的方法吗?它有点单调,但不完全?
class YankeeStadium : IBaseball, IHockey, IFootball
{
StadiumBaseClass _Stadium {get; set;}
// IBaseball
public IBaseball.Whatever {get { return _Stadium.Baseball;} }
// IFootball
public IFootball.Whatever {get { return _Stadium.Hockey;} }
// IHockey
public IHockey.Whatever {get { return _Stadium.Hockey;} }
}
答案 0 :(得分:2)
我认为你根本不应该使用继承。您应该拥有一个带有name属性的Stadium类,而不是YankeeStadium类。
同样,您应该拥有一个属性,例如HasHockey,如果不适用,只需让Hockey属性返回null。
答案 1 :(得分:2)
这似乎是面向常见的面向对象建模问题的一种变体 - 过去,我认为这是一个教育机构建模的问题,其中某个人可能是学生,导师中的一个或多个,讲师,标记,研究员等。
我见过的最佳解决方案是Peter Coad和Jeff De Luca提议的Nebulon Archetypal Domain Shape,也称为Color Modelling。
在您的情况下,实际的体育场将是您的Places
。由于您希望将每个体育场明确地作为一个班级实施,因此每个体育场都代表实际的体育场馆。拥有一个共同的抽象基类可能会有所帮助。课程中的属性将描述体育场的物理属性 - 例如它的实际地址等。
您想要支持的每项不同的运动(您列出棒球,篮球,足球,曲棍球和足球)将被实施为Role
课程,例如BaseballStadium
,BasketballStadium
,FootballStadium
,HockeyStadium
和SoccerStadium
。课程中的属性将描述托管特定运动的具体特征(座位容量可能会有所不同,例如,从一项运动到另一项运动)。
答案 2 :(得分:1)
我建议每个运动场上只有每个体育场的属性,所以你可以打电话
Stadium.Baseball.Fixtures
Stadium.Hockey.Teams
当特定体育场不允许进行某项运动时,请返回该运动的Null Object;
例如
iceRink.Baseball.Available // false
iceRink.Baseball.Fixtures // the empty list
这种方式可以帮助您避免多重继承的问题,特别是像
这样的代码((IBaseball)stadium).Fixtures
答案 3 :(得分:0)
这是另一种方法(我们使用了类似的东西,但不确定它与你的linq实现的对应程度):
让StadiumBaseClass实现具有基本功能的每个接口,然后公开实现类可以使用的虚拟属性a)指示它支持哪些接口,以及b)根据需要改变默认行为。
例如,假设以下接口:
public interface IBaseball
{
void Whatever();
}
public interface IHockey
{
void Whatever();
}
public interface IFootball
{
void Whatever();
}
public interface IBasketball
{
void Whatever();
}
public interface ISoccer
{
void Whatever();
}
您的基类看起来像:
public class StadiumBaseClass : IBaseball, IBasketball, IHockey, IFootball, ISoccer
{
#region IBaseball Members
public virtual bool IBaseballImplemented
{
get
{
return false;
}
}
void IBaseball.Whatever()
{
// Do something
}
#endregion
#region IBasketball Members
public virtual bool IBasketballImplemented
{
get
{
return false;
}
}
void IBasketball.Whatever()
{
// Do something
}
#endregion
#region IHockey Members
public virtual bool IHockeyImplemented
{
get
{
return false;
}
}
void IHockey.Whatever()
{
// Do something
}
#endregion
#region IFootball Members
public virtual bool IFootballImplemented
{
get
{
return false;
}
}
void IFootball.Whatever()
{
// Do something
}
#endregion
#region ISoccer Members
public virtual bool ISoccerImplemented
{
get
{
return false;
}
}
void ISoccer.Whatever()
{
// Do something
}
#endregion
}
将您的个人体育场课程留作:
class YankeeStadium : StadiumBaseClass
{
public override bool IBaseballImplemented
{
get
{
return true;
}
}
public override bool IHockeyImplemented
{
get
{
return true;
}
}
public override bool IFootballImplemented
{
get
{
return true;
}
}
}
答案 4 :(得分:-1)
我认为你应该退后一步,看一下这四种模式中的一些。这正是他们旨在展示解决方案的情况。我建议你开始看看访客模式。 vistior模式允许许多项目(在您的案例中为体育场馆)在其间执行共同的行为。见这里:http://www.dofactory.com/Patterns/PatternVisitor.aspx
这里有四个模式组合的列表:http://www.dofactory.com/Patterns/Patterns.aspx
可能其他人可能会建议另一种模式来查看。装饰图案看起来也很有希望。 (我之前没有使用过decarator模式)。我认为最终你不应该与OO作斗争,而是寻找已发布的解决方案来解决你可能的常见情况。