我有一种情况,我有2个Activity
个对象(假设是空的和预定的活动,不受我控制),它们共享一些行为,比如预订活动的人,活动的房间发生,活动类型,主题等。
我创建了两个包装器对象(EmptyWrapper
和ScheduledWrapper
),它们有一个超类ActivityWrapper
,它实现了两个子系统共有的一些方法,并为子包装器提供了一些抽象方法/属性作出相应的回应。他们的行为非常相似,但有一个至关重要的区别,你只能安排活动,如果它是一个空位!结构是这样的(非常简化的代码):
public class EmptyWrapper : AppWrapper
{
EmptySlot _emptySlot;
public EmptySlotWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public override string Room;
{
get{ return _emptySlot.Room;}
}
public override string Person
{
get{ return _emptySlot.Person;}
}
public override string AppType;
{
get{ return "Empty";}
}
public override bool IsAppSlot()
{
return false;
}
public override bool IsEmptySlot()
{
return true;
}
public override bool CanPerformOperations()
{
return true;
}
public void ReserveApp(ObjWithActivityInfo actObj)
{
(...)
}
}
ActivityWrapper
类似但是包裹的对象不同,bools对IsAppSlot
返回true,IsEmptySlot
为false而CanPerformOperations
为false,没有{ {1}}方法。
接下来是基类:
ReserveApp()
在我的代码中,我只想引用public abstract class AppWrapper
{
public abstract string Collaborator { get; }
public abstract string Room { get; }
public abstract string AppType { get;}
public AppWrapper()
{ }
public abstract bool IsAppSlot();
public abstract bool IsEmptySlot();
public abstract bool CanPerformOperations();
public virtual string GetTextToShow()
{
return Person + " - " + Room;
}
(...)
}
,因为对于一般操作(显示信息和外观),我不需要实现。当我需要预订空槽的活动时,问题就出现了。在这一点上,在我的代码中,我将ActivityWrapper
转换为AppointmentWrapper
并保留活动的插槽(它仍然是EmptyWrapper
,但它保留给所选活动),否则如果演员表不成功,我不会做任何事情,因为它不是正确的EmptySlot
类型。
这是正确的,还是应该在两个包装器中实现Activity
方法并让ReserveActivity()
什么都不做?
或者我应该以另一种方式做到这一点?也许改变班级的结构?
很抱歉这篇长篇文章。
答案 0 :(得分:1)
向不需要它的类添加函数是没有意义的。它会破坏你的继承点。
我会安全演员......
var i = obj as theClass
然后测试null。我将使用一些linq来选择具有您定义的属性的所有对象,以指示它们被设置为true的类型。
你可以以其他方式做到这一点,并保存自己的演员和测试,但这意味着设计对于局外人来说不那么明显。
我认为这是一个品味问题,但更喜欢你做的方式。我不确定我喜欢bool属性来识别类型。如果再次继承基类怎么办?此外,您可以强制转换以识别类型 - 具有更深层对象结构的类型可能更有用。
我同意你希望使用抽象类的集合。
答案 1 :(得分:1)
在我必须处理类似问题的几个场合中,我倾向于认为创建接口以识别多个对象的常见功能然后创建抽象方法,继承类将以您的方式实现它真的更优雅提及。
e.g。
public interface IAppSlotContainer
{
void relevant_Method_When_ObjectIsAppSlot();
}
public interface IEmptySlotContainer
{
void relevant_Method_When_ObjectIsEmptySlot();
}
public class EmptyWrapper : AppWrapper, IAppSlotContainer, IEmptySlotContainer
{
public EmptyWrapper(EmptySlot emptySlot) : base()
{
this._emptySlot = emptySlot;
}
public override string Id
{
get { return _emptySlot.AgendaId; }
}
public void relevant_Method_When_ObjectIsEmptySlot()
{
}
public void relevant_Method_When_ObjectIsAppSlot()
{
}
}
然后,不是覆盖抽象方法“IsEmpty”并将其实现为“return true”,只需检查对象是否是IEmptySlotContainer的实例,将其强制转换为该接口,然后执行与接口相关的命令。 对我来说,它更通用,更优雅......
希望这会有所帮助......