为提供许多服务的对象建模的正确方法是什么?

时间:2009-04-13 09:06:54

标签: design-patterns oop

基本上我有一个实体(称为Session),它将提供许多不同的服务。用户可以选择性地打开或关闭每个服务(登录或注销)。我不确定代表这个的最佳设计是什么。见UML

从编程用例的角度来看,与Session实例的交互:

Session session = new Session( "1234" ); // 1234 is the userid
session.start();

session.serviceSignIn( ServiceType.DELICIOUS );
.... do stuff ...
session.serviceSignOut( ServiceType.DELICIOUS );

session.serviceSignIn( ServiceType.MAGNOLIA );
.... do stuff ...
session.serviceSignOut( ServiceType.MAGNOLIA );  

另一种可能的设计:

session.delicious().signIn();
.... do stuff ...
session.delicious().signOut();

session.magnolia().signIn();
.... do stuff ...  
session.magnolia().signOut();

我更喜欢哪一个?我犯了什么错误?

4 个答案:

答案 0 :(得分:1)

为什么要明确命名服务?据推测,这将被连接到某些GUI或其他界面正确吗?可能足以通过像“美味”这样的字符串来引用它们。另外,为什么不让每个服务都成为可以自我签约的课程呢?

interface Service {
    String getName();
    void signin();
    void signout();
    State getState(); // state could be signed in signed out or signing in perhaps
} 

class Services {
   void addService(Service service);
   void removeService(Service service);
   Service getService(String serviceName);

   ...
}

您还应该使Service接口具有对服务进行操作的操作,例如添加书签。

答案 1 :(得分:0)

我认为,通过第一种方法,您不会以任何方式限制您的设计。您可以动态加载服务,并在将来轻松添加新服务(因为没有代码绑定到确切的服务类型 - 如第二种方法)。

答案 2 :(得分:0)

我认为做出这个决定的驱动因素应该是美味和玉兰提供的实际服务。他们是同一个服务?如果他们共同的唯一共同点是登录/注销行为,那么我会采用第二种方法,可能会使用登录/注销功能作为某种界面/混合。

答案 3 :(得分:0)

对我而言,它看起来像一个经典的Facade模式,你谈到服务是为了SOA实现吗?或许看看Service Facade。我将使用一个单一的入口点来描述(Facade),其中的参数驱动Factory返回特定的实现。以下示例允许您在不更改实现的情况下添加其他服务。

interface ISessionFacade
{
    void ServicesSignIn(string serviceType);

    void ServiesSignOut(string serviceType);
}

interface ISessionService
{
    void ServicesSignIn();

    void ServiesSignOut();
}

class ServiceFactory
{
    public static ISessionService CreateService(string serviceType)
    {
        ISessionService sessionService = null;

        // TODO: Configuration lookup of serviceType, returning a fully qualified class name to load

        // TODO: Dynamically load class, perhaps this should be a singleton?

        return sessionService;
    }
}

class Session : ISessionFacade
{
    public void ServicesSignIn(string serviceType)
    {
        ISessionService serviceSession = ServiceFactory.CreateService(serviceType);
        serviceSession.ServicesSignIn();
    }

    public void ServiesSignOut(string serviceType)
    {
        ISessionService serviceSession = ServiceFactory.CreateService(serviceType);
        serviceSession.ServiesSignOut();
    }
}