2013-04-23 85 views
1

我想重构一些基本上有对象类型的switch语句的代码,并调用基于该类型的特定服务方法。我试图保持尽可能基本相同的代码。按对象类型解析服务的设计模式?

if (user is Employee) 
{ 
    _userService.DoSomething(user); 
} 
else if (user is Manager) 
{ 
    _managerService.DoSomething(user); 
} 
else if (user is Executive) 
{ 
    _executiveService.DoSomething(user); 
} 

我想抽象服务调用接口和减少代码行数。我的问题在于ServiceResolver部分,是否存在与此类问题相关的特定设计模式?我可以轻松创建一个具有switch语句的类,该语句返回实现该接口的正确服务,但看起来并不像我想要的那样干净。有什么建议么?我已经在使用结构图构造函数注入,可以使用条件或其他?

public interface IUserDoSomethingService 
{ 
    void DoSomething(User user) 
} 

var userDoSomethingService = _userDoSomethingServiceResolver(user); 
userDoSomethingService.DoSomething(user); 

回答

3

简单!我会假设你不需要施放(你实际上有强类型的类型)。

在这种情况下,你只需要一个通用的IDoSomethingService

public interface IServiceDoSomethingOn<in T> 
{ 
    void DoSomethingOn(T thing); 
} 

现在上的服务电话,你只需要调用...

public void DoSomethingOnSomethingElse<T>(T thatSomething) 
{ 
    var service = ServiceResolver.Current.Resolve<IServiceDoSomethingOn<T>>(); 
    service.DoSomethingOn(thatSomething); 
} 

编辑:半通用的解决方案。警告我不知道结构图如何处理协方差和逆变。所以继承可能无法工作。

public void DoSomethingOnSomethingElse(object thatSomething, Type type) 
{ 
    var genericMethod = this.GetType().GetMethods() 
         .Single(x => x.IsGeneric && x.Name == "DoSomethingOnSomethingElse"); 
    var method = genericMethod.MakeGenericMethod(type); 
    method.Invoke(this, new object[]{thatSomething}); 
} 
+0

我认为这是正确的轨道。对于ServiceResolver.Current.Resolve >()有没有办法解决而不通过T?我没有定义T泛型,只是对象类型。 – NullReference 2013-04-23 19:44:43

+0

Gahh ...不是我想听的.... – Aron 2013-04-24 01:15:23

0

我的想法是:

public interface IUserDoSomethingService { 
    void DoSomething(Employee user); 
    void DoSomething(Manager user); 
    void DoSomething(Executive user); 
} 
1

为什么不抽象工厂模式

public class UserServiceFactory : IUserServiceFactory { 
    public EmployeeServiceFactory(IUserService employeeService 
    , IUserService managerService 
    , IUserService executiveService) { 

    //null guards 
    this.employeeService = employeeService; 
    this.managerService = managerService; 
    this.executiveService = executiveService; 
    } 
} 

从这里,你有两个选择,要么使用传统的if-else语句或策略模式按对象类型来解决。

如果其他例子(内UserServiceFactory法):

public void DoSomething(User user) { 
    if (user is Employee) { 
    employeeService.DoSomething(user); 
    } 
    else if (user is Manager) { 
    managerService.DoSomething(user); 
    } 
    else if (user is Executive) { 
    executiveService.DoSomething(user); 
    } 
} 

解决按对象类型:

public void DoSomething(Employee user) { 
    employeeService.DoSomething(user); 
} 
public void DoSomething(Manager user) { 
    managerService.DoSomething(user); 
} 
public void DoSomething(Executive user) { 
    executiveService.DoSomething(user); 
} 

应该有另一种方式来做到这一点,通过使用命名了配置,但我仍然无法做到这一点。

中直接调用用法:

public void CallUser() { 
    // declare the services and user here 
    UserServiceFactory userServiceFactory = new UserServiceFactory(employeeService 
    , managerService 
    , executiveService); 
    userServiceFactory.DoSomething(user); 
} 

其他服务用法,注射工厂,而不是服务集合。

public class UserServiceConsumer:IUserServiceConsumer { 
    public UserServiceConsumer(IUserServiceFactory userServiceFactory) { 
    this.userServiceFactory = userServiceFactory; 
    } 
    IUserServiceFactory userServiceFactory; 

    public void ConsumeFactory(User user) { 
    //do some validation maybe 
    userServiceFactory.DoSomething(user); 
    } 
} 

听起来很复杂,但在你理解后很简单。