【问题标题】:Design Question: Which is Better practice?设计问题:哪个是更好的实践?
【发布时间】:2010-01-09 23:09:12
【问题描述】:

我有 3 个不同的 Web 服务器来处理用户数据(用户名/密码/电子邮件/等)。我分别有 3 个不同的 Web 服务调用,所以我创建了 3 个不同的类来调用相同的信息(getUsernamesetUsernamegetEmailsetEmail 等)。在主类中,我实例化每个 webservice-call 对象,当我请求新的用户名和密码时,我调用每个类的 createUsername() 方法(提供数据)。

您对如何应用设计模式来解决这个问题有什么建议吗?我想创建一个具有createUsername() {} 方法的类,在此我将调用每个 webservice-classes 并将每个结果存储在预定义的数组中。有没有人有任何建议或更好的做法?

目前我有:


class webservice1calls {
function createUser($username, $password) {}
function deleteUser($username, $password) {}
function createGroup($groupname) {}
function deleteGroup($groupname) {}
}

class webService2calls { function createUser($username, $password) {} //different implementation function deleteUser($username, $password) {} //different implementation function createGroup($groupname) {} //different implementation function deleteGroup($groupname) {} //different implementation }

class webService3calls { function createUser($username, $password) {} //different implementation function deleteUser($username, $password) {} //different implementation function createGroup($groupname) {} //different implementation function deleteGroup($groupname) {} //different implementation }

//My "like a proxy" class:

class webServiceCalls { function createUser($username, $password) { $ws1 = new webService1calls(); $ws2 = new webService2calls(); $ws3 = new webService3calls();

$res1 = $ws1->createUser($username, $password);
$res2 = $ws2->createUser($username, $password);
$res3 = $ws3->createUser($username, $password);

// return result depending $res1,$res2 and $res3 values

}

//and the call is done from another class somewhat like this:

class doThings { function run() { $ws = new webServiceCalls(); $ws_res = $ws->createUser(); } }

我认为上述表示将帮助您了解当前 设计(也许对问题有更好的理解。 谢谢!

【问题讨论】:

  • 请改写你的问题,它完全模棱两可,并没有描述你的实际问题。
  • 对不起.. 我无法访问我的电子邮件帐户和 stackoverflow 帐户.. 我创建了一个新帐户,因此我将使用不同的用户名再次发布我的问题:(你可以在这里找到新修订的问题(我希望我已经清除了所有模糊的部分):stackoverflow.com/questions/2048022/…很抱歉给您带来不便:(

标签: php design-patterns oop


【解决方案1】:

哎呀!首先,由于它们非常相似,它们应该共享一个公共基类或使用一个接口:

interface WebService {
    function createUser($username, $password);
    function deleteUser($username, $password);
    function createGroup($groupname);
    function deleteGroup($groupname);
}

class MyService implements WebService {
    function createUser($username, $password) {}
    function deleteUser($username, $password) {}
    function createGroup($groupname) {}
    function deleteGroup($groupname) {}
}

其次,我希望您的服务实际上没有被称为 1,2,3。如果是的话,那对我来说,也许你应该使用某种形式的数组。

我不喜欢你关于“代理”类的想法。您是否总是使用所有 3 项服务,或者这是某种图书馆,您只包含您需要的服务?你没有提供足够的信息来说明你真正想要完成的事情。

【讨论】:

    【解决方案2】:

    我喜欢将每个服务器的实现保存在一个单独的类中的想法,我也喜欢 Mark 使用接口的想法。我也喜欢你对代理类的想法,但不是你提出的形式。我会创建一个充当各种池的类。像这样的:

    class WebServicePool implements WebService {
    
        private $webServices = array();
    
        public function registerWebService($service) {
            if($service instanceof WebService)
                $this->webServices[] = $service;
        }
    
        function createUser($username, $password) {
            foreach($this->webServices as $service)
                $service->createUser($username, $password);
        }
        // ...
    }
    

    您还可以使用魔术方法来代理此功能:

    class WebServicePool {
    
        private $webServices = array();
    
        public function registerWebService($service) {
            if($service instanceof WebService)
                $this->webServices[] = $service;
        }
    
        function __call($name, $arguments) {
            foreach($this->webServices as $service)
                call_user_func_array(array($service, $name), $arguments);
        }
    }
    

    这样,如果您向界面添加更多功能,则无需更新池类。希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      您如何看待 Model - ModelMapper 拱门? Zend Framework 使用这种方法。您可能有以下类:(为了更好地理解愚蠢的命名约定)

      • Model_User
      • Mapper_User_Email
      • Mapper_User_Name
      • Mapper_User_Password

      并且各个映射器读取所需的数据,第 3 方类只调用 Model_User->getName()

      编辑: 示例用法:

      //simple code:
      $user = new Model_User();
      echo "Your name is: " . $user->getName();
      
      //Model_User:
      public function getName() {
          if($this->_name = null) {
              $this->getNameMapper()->getName($this);
              //getNameMapper() returns a Mapper_User_Name object
          }
          return $this->getName();
      }   
      
      //Mapper_User_Name:
      public function getName($user) {
          $name = "john"; /*magic here, the class communicate with the service that holds names*/
          $user->setName($name);
      }
      

      仅作为示例,getter 和 setter 可能更具防御性。

      【讨论】:

      • 你是否建议(只是为了确保)我可以根据它们的属性创建对象(即一个对象来处理用户的所有操作和另一个处理组操作的对象)......有我理解正确吗?感谢您的意见!
      【解决方案4】:

      我会采取完全不同的方法。 REST interface 非常适合您尝试执行的操作,这是标准 CRUD 命令。

      【讨论】:

      • 服务器之间的通信是由作者已经列出的特定类实现的,与问题的性质无关。作者正在寻找一种方法来管理三个不同服务器的三个独立接口,而不是寻找新的通信介质或协议。
      猜你喜欢
      • 2012-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-12
      • 2019-10-22
      • 2013-10-07
      • 2018-06-11
      相关资源
      最近更新 更多