简体   繁体   English

设计问题:哪种方法更好?

[英]Design Question: Which is Better practice?

I have 3 different web servers which handle user data (username/passwd/email/etc.). 我有3个不同的Web服务器来处理用户数据(用户名/密码/电子邮件/等)。 I have 3 different web service calls respectively, so I've created 3 different classes which calls for the same information ( getUsername , setUsername , getEmail , setEmail , etc.). 我分别有3个不同的Web服务调用,因此我创建了3个不同的类,它们调用相同的信息( getUsernamesetUsernamegetEmailsetEmail等)。 From the main class I instantiate each webservice-call objects and when I have a request for a new username, password I call the createUsername() method of each class (provisioning the data). 在主类中,我实例化了每个webservice-call对象,当我请求一个新的用户名和密码时,我调用了每个类的createUsername()方法(提供数据)。

Do you have any suggestions on how to apply a design pattern for this problem? 您对如何针对此问题应用设计模式有任何建议吗? I thought of making a class which will have a method createUsername() {} and in this I would call each of the webservice-classes and store each result in a predefined array. 我考虑过创建一个类,该类将具有方法createUsername() {} ,在这种情况下,我将调用每个webservice-classs并将每个结果存储在预定义的数组中。 Does anyone have any suggestion or a better practice? 有没有人有任何建议或更好的做法?

currently i have: 目前我有:


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(); } }

I thought that the above representation would help you understand the current design (and maybe a better understanding of the problem. thanks! 我认为上述表示形式将帮助您理解当前的设计(也许可以更好地理解问题。谢谢!

Eep! Firstly, since these are so similar, they should share a common base class or use an interface: 首先,由于它们是如此相似,因此它们应该共享一个公共基类或使用一个接口:

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) {}
}

Secondly, I hope your services aren't actually called 1,2,3. 其次,我希望您的服务实际上没有被称为1,2,3。 If they are, that suggests to me that maybe you should be using some form of an array. 如果它们是,那对我建议也许您应该使用某种形式的数组。

I don't like your idea of a "proxy" class. 我不喜欢您关于“代理”课程的想法。 Are you always using all 3 services, or is this some sort of library where you just include the service you need? 您是否一直使用全部三种服务,还是仅在其中包含所需服务的某种库? You haven't provided enough info about what you're actually trying to accomplish. 您尚未提供有关您实际要完成的工作的足够信息。

What do you think about a Model - ModelMapper arch? 您如何看待Model-ModelMapper架构? Zend Framework uses this approach. Zend Framework使用这种方法。 You could have possibily the following classes: (silly naming convention for better understanding) 您可能有以下课程:(愚蠢的命名约定,以便更好地理解)

  • Model_User
  • Mapper_User_Email
  • Mapper_User_Name
  • Mapper_User_Password

And the individual mappers read the needed data, the 3rd party class only calls Model_User->getName() 各个映射器读取所需的数据,第三方类仅调用Model_User-> getName()

Edit: Example usage: 编辑:用法示例:

//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);
}

Example only, the getters and setters could be more defensive. 仅作为示例,获取器和设置器可能更具防御性。

I like the idea of keeping each server's implementation in a separate class, and I also like Mark's idea of utilizing an interface. 我喜欢将每个服务器的实现保存在一个单独的类中的想法,我也喜欢Mark使用接口的想法。 I'm also fond of your idea of a proxy class, but not in the form that you presented. 我也很喜欢您对代理类的想法,但不喜欢您提出的形式。 I would create a class that acts as a pool of sorts. 我将创建一个充当各种池的类。 Something like this: 像这样:

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);
    }
    // ...
}

You could also use magic methods to proxy this functionality: 您还可以使用魔术方法来代理此功能:

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);
    }
}

That way, if you add more functions to your interface, you won't need to update your pool class. 这样,如果您向接口添加更多功能,则无需更新池类。 Hope this helps! 希望这可以帮助!

I would take a completely different approach. 我会采取完全不同的方法。 A REST interface would be perfect for what you're trying to do, which are the standard CRUD commands. REST接口非常适合您要执行的操作,这是标准的CRUD命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM