Quiero escribir un módulo (marco específico), que envolvería y ampliaría Facebook PHP-sdk (https://github.com/facebook/php-sdk/). Mi problema es cómo organizar clases de una manera agradable.sustitución de herencia de varios niveles
Así que entrar en detalles - Facebook PHP-SDK consta de dos clases:
- BaseFacebook - clase abstracta con todo el SDK cosas hace
- Facebook - se extiende BaseFacebook, e implementa métodos relacionados con la persistencia-abstractos padres con el uso de sesión predeterminado
Ahora tengo algunas funciones para agregar:
- Facebook clase sustitución, integrados con clase de sesión marco
- métodos abreviados, que las llamadas de la API de ejecución, que utilizan en su mayoría (a través de BaseFacebook :: API()),
- métodos de autorización, así que no tengo que volver a escribir este lógica cada vez,
- configuración, aspirado de clases de la arquitectura, en restaurantes en vez de pasar como params
- almacenamiento en caché, integrada con el módulo de memoria caché marco
sé que algo ha ido muy mal, porque tengo demasiada herencia eso no se ve muy normal. Envolver todo en una clase de "extensión compleja" también parece demasiado. Creo que debería tener pocas clases de trabajo juntas, pero me meto en problemas como: si la clase de caché realmente no amplía y reemplaza el método BaseFacebook :: api(), las clases de autenticación y taquigrafía no podrán usar el almacenamiento en caché.
Tal vez algún tipo de patrón estaría justo aquí? ¿Cómo organizarías estas clases y sus dependencias?
EDITAR 04.07.2012
bits de código, relacionados con el tema:
Así es como la clase base de Facebook PHP-SDK:
abstract class BaseFacebook {
// ... some methods
public function api(/* polymorphic */)
{
// ... method, that makes api calls
}
public function getUser()
{
// ... tries to get user id from session
}
// ... other methods
abstract protected function setPersistentData($key, $value);
abstract protected function getPersistentData($key, $default = false);
// ... few more abstract methods
}
Normaly clase extiende Facebook e impone esos métodos abstractos. He sustituido con mi substitude - clase Facebook_Session:
class Facebook_Session extends BaseFacebook {
protected function setPersistentData($key, $value)
{
// ... method body
}
protected function getPersistentData($key, $default = false)
{
// ... method body
}
// ... implementation of other abstract functions from BaseFacebook
}
Ok, entonces este se extienden más con métodos abreviados y las variables de configuración:
class Facebook_Custom extends Facebook_Session {
public function __construct()
{
// ... call parent's constructor with parameters from framework config
}
public function api_batch()
{
// ... a wrapper for parent's api() method
return $this->api('/?batch=' . json_encode($calls), 'POST');
}
public function redirect_to_auth_dialog()
{
// method body
}
// ... more methods like this, for common queries/authorization
}
No estoy seguro, si esto no es demasiado mucho para una sola clase (autorización/métodos abreviados/configuración). Luego viene otra capa de extensión: caché:
class Facebook_Cache extends Facebook_Custom {
public function api()
{
$cache_file_identifier = $this->getUser();
if(/* cache_file_identifier is not null
and found a valid file with cached query result */)
{
// return the result
}
else
{
try {
// call Facebook_Custom::api, cache and return the result
} catch(FacebookApiException $e) {
// if Access Token is expired force refreshing it
parent::redirect_to_auth_dialog();
}
}
}
// .. some other stuff related to caching
}
Ahora esto funciona. Nueva instancia de Facebook_Cache me da toda la funcionalidad. Los métodos abreviados de Facebook_Custom utilizan el almacenamiento en caché, porque Facebook_Cache sobreescribió el método api().Pero aquí está lo que me está molestando:
- Creo que es demasiada herencia.
- Todo está muy bien acoplado, como mire cómo tuve que especificar 'Facebook_Custom :: api' en lugar de 'parent: api', para evitar el método de bucle api() en la extensión de la clase Facebook_Cache.
- Desorden general y fealdad.
Así que de nuevo, esto funciona, pero solo estoy preguntando sobre los patrones/formas de hacerlo de una manera más limpia y más inteligente.
favor proporcionar algunos detalles más para conseguir más cerca de la solución .. –
He añadido bits de código, Sory que se tardó tanto tiempo. – Luigi
Por cierto; herencia múltiple es una clase que extiende más de otra clase. Eso es algo completamente diferente. – Sherlock