Les interfaces ne sont pas directement utilisées pour la réutilisation du code. Ils sont pour l'abstraction. Ils permettent aux classes qui utilisent le modèle de vérifier l'interface au lieu de la classe de modèle de base. De cette façon, il sépare l'implémentation de la déclaration d'interface. Par conséquent, si votre méthode fait quelque chose avec une classe template
, la vérification d'un objet de l'instance template
permet de coder en dur une dépendance sur cette classe. Mais en réalité vous ne vous souciez pas de la classe que vous obtenez, vous vous souciez seulement si elle adhère à l'interface iTemplate
(puisque c'est tout ce que vous appelez de toute façon).
public function foo(Template $template) {
vs:
public function foo(iTemplate $template) {
Maintenant, dans la mesure où le code de réutilisation, les interfaces ne sont pas vraiment conçus pour cela. L'héritage est généralement. Fondamentalement, pensez à l'héritage comme l'extension d'une abstraction. Permettez-moi de vous donner un exemple:
Si vous deviez créer un ensemble de classes pour les oiseaux, vous pourriez l'aborder avec l'héritage et sans elle. Voyons voir comment nous pourrions le faire sans:
interface iBird {
public function fly();
public function speak();
public function swim();
public function walk();
}
class Duck implements iBird {
public function fly() {
//Fly here
}
public function speak() {
// Quack here
}
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Turkey implements iBird {
public function fly() {
//Fly here, but limited
}
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
public function walk() {
//Walk here
}
}
Maintenant, ceci est un exemple simple, mais vous pouvez voir que dans ces deux oiseaux, les walk()
fonctions seront probablement identiques (et elle contreviendrait ainsi DRY) ...
Voyons comment cela pourrait ressembler à un seul héritage de niveau:
abstract class Bird implements iBird {
public function fly() {
//Fly here
}
abstract public function speak();
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Duck extends Bird {
public function speak() {
//Quack here
}
}
class Turkey extends Bird {
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
}
maintenant, vous pouvez voir que nous venons de rÉUTILISÉS 3 des méthodes! Nous n'avons pas déclaré speak()
, car il sera toujours dépassé (puisque deux oiseaux ne se ressemblent pas).
Ça a l'air bien, non? Eh bien, en fonction de nos besoins, nous pouvons vouloir ajouter d'autres types abstraits. Disons donc que nous faisions beaucoup de différents types d'oiseaux ... Nous en aurions certains qui ne nageraient pas, donc nous pourrions créer une classe abstraite NonSwimmingBird
qui étend Bird
, mais qui jette l'exception pour nous. Ou un NonFlyingBird
, ou un ShortRangeBird
...
Maintenant, nous sommes vraiment sur la piste en ce qui concerne la réutilisation du code, mais nous touchons un mur dans une autre zone. Supposons que nous ayons un oiseau qui ne vole pas ou nage. De quelle classe héritons-nous? De toute façon, nous dupliquons le code. Nous devons donc trouver une autre issue. Eh bien, comment le faisons-nous? Grâce à Design Patterns ... Au lieu de l'héritage direct, nous pourrions utiliser un modèle de décorateur pour ajouter ces traits à la volée. (Il y a d'autres modèles qui peuvent être utilisés ici, le but est de montrer que l'héritage seul ne répondra pas à tous les besoins.) Et les patterns ne le seront pas non plus Vous avez besoin d'une bonne architecture utilisant les deux mondes selon vos besoins ...
Le fait est que tout dépend de vos besoins. Si vous n'avez que 2 "classes" d'objets, vous allez construire quelque chose de beaucoup plus simple que si vous prévoyez en avoir des milliers. Le but de ce que j'ai écrit ici est de démontrer comment vous pouvez utiliser l'héritage direct pour appliquer certains principes DRY (mais aussi comment l'héritage direct peut aussi entraîner une duplication de code). La grande chose, c'est de ne pas essayer de rester sur DRY juste parce que vous ne voulez pas vous répéter. Stick à DRY, mais assurez-vous que vous combinez et d'étendre là où c'est raisonnable, sinon vous vous créez un mal de tête de maintenance. Stick à la Single Responsibility Principal, et vous devriez être bien ...
pouvez-vous me dire où avez-vous trouvé ce code? Je suis dans la phase d'apprentissage et je cherche à apprendre par des exemples. – dole