我有一些课程,
public abstract class Event{
}
public class EventA : Event{
public string Id{get; private set;}
public string Name{get; private set;}
public EventA(string id, string name){
Id = id;
Name = name;
}
}
public class EventB : Event{
public string Prop{get; private set;}
public string Prop1{get; private set;}
public EventA(string prop, string prop1){
Prop = prop;
Prop1 = prop1;
}
}
public class EventC : Event{
// .........
}
public class EventD : Event{
// .........
}
public class SomeClass{
public Event SomeMethod(){
switch(SomeCondition){
case "FirstCondition":
return new EventA(...);
case "SecondCondition":
return new EventC(...);
case "ThirdCondition":
return new EventC(...);
case "FourthCondition":
return new EventD(...);
}
}
}
现在我有2个问题,
1)事件类在这里应该是接口类还是抽象类?
2)如何将switch语句移到更有意义的类中。我应该在这里使用Factory还是缺少任何设计模式?
答案 0 :(得分:3)
简而言之,interface
在实现者之间共享合约,abstract class
在继承者之间共享合约和实现。
由于语言的限制,您只能从一个类继承,因此,仅在需要时才使用抽象类,以防用户需要从另一个类继承并实现您的合同。
这里似乎没有实现,因此接口是更好的选择。
我真的没有第二个问题。是的,将您的交换机封装在一个类中将被称为工厂模式,并且并非罕见。但是看来您已经做到了。所以...没事做。
答案 1 :(得分:3)
从接口开始绝不是一个坏主意,因为许多设计模式都基于它们,例如,如果您想实现IoC或工厂。
因此事件可以成为IEvent:
public interface IEvent
{
}
现在,假设您必须以某种方式初始化所有事件,或者它们应该共享一些通用的基本实现,那么您可以使用一个抽象类,所有事件实现都将继承自该类:
public abstract BaseEvent : IEvent
{
protected BaseEvent(string name);
//Method must be implemented
public abstract SomeMethod();
//Method can be overriden
public virtual DoSomething()
{
}
}
然后,您可以创建实际的“事件”实现,它们都共享一个公共接口和一些基本功能,可以使用多态性对其进行修改,例如:
public EventA : BaseEvent
{
public EventA() : base("Event A")
{
}
public override SomeMethod()
{
}
public override DoSomething()
{
}
}
最后,要回答您的问题,您将如何初始化对象?
这确实取决于您的应用程序需求,这种实现方式是否会经常更改?您是否需要一个抽象层,以允许您稍后在较新的或不同的技术(例如新的数据库系统)上替换整个实现,这是一个涉及不同团队的大项目吗?
对于一个永远不会改变的简单系统,您可以做已经做的事情;对于一个更复杂的系统,您可以使用IoC容器,您在问题中建议的工厂模式或两者结合使用,这是工厂模式的简单实现:
public interface IEventFactory
{
IEvent CreateEvent(string someCondition);
}
public class EventFactory : IEventFactory
{
public IEvent CreateEvent(string someCondition)
{
switch(SomeCondition){
case "FirstCondition":
return new EventA();
case "SecondCondition":
return new EventB();
case "ThirdCondition":
return new EventC();
case "FourthCondition":
return new EventD();
}
}
要使用工厂,您可以使用依赖项注入容器(例如Unity)进行注册,这是一个非常简单的示例:
var container = new UnityContainer();
container.RegisterType<IEventFactory, EventFactory >();
每当您需要工厂时:
var eventFactory = container.Resolve<IEventFactory>();
var someEvent = eventFactory.CreateEvent("SomeCondition");
当然,尽管这种设计在数据库抽象层等方面很有意义,但对于事件系统来说可能会显得过分过分。