2010-03-01 7 views
3

J'ai lu beaucoup d'articles sur le développement de classes (j'utilise php), avec les lignes d'étiquette: 'évolutif, robuste, maintenable et extensible'.Comment créer une classe "véritablement extensible"

Mais en tant que débutant, j'ai créé des cours qui sont, selon moi, "juste abstraits". Signification Je viens de séparer un groupe ou des codes répétitifs et de les mettre dans une classe et de fournir des méthodes pour accéder aux tâches courantes. Le truc, c'est que je ne trouve pas un moyen de rendre ma classe extensible (je connais le concept des classes abstraites et autres, je les utilise même, mais juste pour définir les méthodes que suivront mes autres classes). La chose est, Je me trouve toujours l'édition de la classe de base juste pour ajouter des fonctionnalités.

Des conseils pour rendre ma classe extensible? (J'ai cherché sur google et tout ce qui ressort est des explications de classes abstraites, d'interfaces et de POO, pas de discussions sur les pointeurs ou quelques astuces pour faire des classifications extensibles).

Oh, btw, allez-y doucement, j'ai commencé la programmation "réelle" oop il y a 9 mois (l'université d'où je viens m'a donné des théories sur la POO, mais ils nous ont fait TRAVAILLER PROCÉDURALEMENT, parce que il respecte les dates limites des projets, et cela a duré 4 ans jusqu'à ce que je sois diplômé).

Répondre

2

Vous devriez vérifier le livre Design Patterns: Elements of Reusable Object-Oriented Software

Le problème avec Faire des classes extensibles, comme vous l'avez découvert, est en train de décomposer le système en objets utiles et réutilisables. La tâche est difficile car de nombreux facteurs entrent en jeu: encapsulation, granularité, dépendance, flexibilité, performance, évolution, réutilisabilité, etc. Essayez-vous de modéliser un scénario réel ou vous concentrez-vous sur la communication/collaboration et les dépendances au sein de votre application?

Voici un exemple qui montre un peu ce que vous cherchez. Il y a certainement beaucoup plus, de bien meilleurs exemples:

Je voulais développer un système de mise en cache qui offrait à mes développeurs une API simple et normalisée, peu importe où/où ils mettaient en cache quelque chose. Qu'est-ce que je veux dans un système de cache (au niveau de base)?

  • Je veux être en mesure de mettre en cache quelque chose (set)
  • Je veux être en mesure de récupérer que quelque chose (obtenir)
  • Je veux être en mesure d'invalider le cache (supprimer)

je suis venu avec ceci:

abstract class MyNs_Cache 
{ 
    abstract public function Set($key, $data, $ttl); 
    abstract public function Get($key); 
    abstract public function Delete($key, $ttl); 
} 

Il y a ma classe de base extensible.Je l'ai ensuite eu trois classes de mise en cache MyNs_Cache_Fs, MyNs_Cache_Apc et MyNs_Cache_Memcache

class MyNs_Cache_Fs 
{ 
    ... 

    public function Set($key, $data, $ttl) 
    { 
     // here I use fopen/fwrite/etc. to create the cached data 
    } 

    public function Get($key) 
    { 
     // here I retrieve the file from the filesystem (if it exists) 
    } 

    public function Delete($key) { ... } 
} 

C'est assez simple. Il implémente le cache en termes de FileSystem. Il n'offre rien après ma classe originale.

class MyNs_Cache_Apc 
{ 
    ... 

    public function Set($key, $data, $ttl) 
    { 
     return apc_add($key, $data, $ttl); // NOT A FILESYSTEM CALL 
    } 

    public function Get($key) { ... } // you get the idea. 

    // This is specific to APC, so I add the functionality HERE 
    // NOT in my main Caching class. 
    public function PurgeCache() 
    { 
     return apc_clear_cache(); 
    } 
} 

Mon cache APC fait tout ce que je veux dans un système de mise en cache (set/get/supprimer) mais il offre également la possibilité d'effacer l'intégralité du cache (quelque chose qui est pas utile pour mon cache FileSystem et impossible avec memcached)

class MyNs_Cache_Memcache 
{ 
    // Memcached needs a pool of servers. APC and filesystem don't. 
    private $servers = array(..); 

    // It also uses a memcached object. 
    private $conn; 

    public function __construct() 
    { 
     $this->conn = new Memcached; 

     foreach ($this->$servers as $server) 
      $this->AddServer($server); 
    } 
    ... // we do all the standard stuff using memcached methods 

    // We also want to be able to manage our connection pool 
    public function AddServer($server) 
    { 
     $this->conn->addServer(...); 
    } 

    // And in some cases, we use inc/dec from memcached 
    // APC doesn't have this, and it makes little sense in a filesystem 
    public function Increment($key) { ... } 
} 

maintenant, je sais que je peux toujours obtenir un de mes objets de cache et juste avec obj- $> get (« some_key ») et je vais toujours obtenir un résultat.

De même, j'ai également accès à des fonctionnalités spécifiques à ce que je suis en train de travailler.

1

Vous n'avez pas besoin de modifier votre classe de base pour ajouter des fonctionnalités que vous pouvez remplacer une méthode dans une classe d'enfants, par exemple:

class A { 
public function filter_string($str){ 
    return str_replace ('foo', 'bar', $str); 
} 
} 

class B extends A { 
public function filter_string($str){ 
    return str_replace ('machin', 'chose', parent::filter_string ($str)); 
} 
} 

$a = new A; 
echo $a->filter_string('foo machin'); // echoes 'bar machin' 

$b = new B; 
echo $b->filter_string('foo machin'); // echoes 'bar chose' 
Questions connexes