Re: [PEPr] +1 for Web Services::Services_UseKetchup
| From: | Daniel O'Connor | Date: | Fri, 10 Sep 2010 01:22:49 +0000 |
| Subject: | Re: [PEPr] +1 for Web Services::Services_UseKetchup | ||
| References: | 1 2 3 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-53793@lists.php.net to get a copy of this message | ||
>
> Do you want me to move Services_UseKetchup::__get() to a separate class?
>
> I see no real reason for that. But let me know what exactly you're after.
>
To clarify:
Services_UseKetchup = 80% factory, 20% work-out-my-credentials
Services_UseKetchup_Common = 90% transport and credentials, 10% inspect
standard classes for ids
Services_UseKetchup_* = controllers, manipulating your models and invoking
the transport
and at the moment, everything extends Services_UseKetchup_Common.
I think that you might find it cleaner if you broke some of the inheritance
you've built on and injected specific classes into specific roles. It'll
push you to make very obvious and useful public methods, which will allow
other developers to re-use your code fairly trivially.
IE; along the lines of:
<?php
class TransportLayer {
/**
* Insert your request object, credentials or api token
*/
public function __construct(HTTP_Request2 $request, $token) {
}
/**
* Invokes the request object, combining the credentials as appropriate
*
* *Avoids *instantiating a HTTP_Request2 / new objects at all costs
*/
public function makeRequest(...) {
if ($this->apiToken !== null) {
$url .= '?u=' . $this->apiToken;
}
$this->client
->setHeader('Content-Type: application/json')
->setAuth($this->username, $this->password)
->setMethod($method)
->setUrl($this->endpoint . $url);
if ($data !== null) {
$this->client->setBody($data);
}
$resp = $this->client->send();
return $resp;
}
}
class Items {
/**
* Injected transport, rather than inherited
*/
public function __construct(TransportLayer $transport) {
...
}
public function update(stdClass $item)
{
$id = $this->guessId($item);
$data = json_encode($item);
$resp = $this->transport->makeRequest(
"/items/{$id}.json",
HTTP_Request2::METHOD_PUT,
$data
);
$data = $this->transport->parseResponse($resp);
if ($data !== null) {
return true;
}
return false;
}
}
At the moment, because inheritence is making it easy; it doesn't really
matter if some things are protected or public - you are extending and never
run into trouble.
A good scenario to think about is *how would someone using this library add
another object type in response parsing?
*parseResponse() is protected and in a base class - there's no way I can get
my claws into it and extend it to add in a new "'XYZ Deleted Successfully";
then have that re-used by the rest of the code.
***
*Does* *that make a bit of sense?