将多个不同的实例切换到一个类中

时间:2018-11-09 08:16:58

标签: c#

我有一些课程,

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还是缺少任何设计模式?

2 个答案:

答案 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");

当然,尽管这种设计在数据库抽象层等方面很有意义,但对于事件系统来说可能会显得过分过分。