Maison  >  Article  >  Java  >  Résumé des sept principes des modèles de conception

Résumé des sept principes des modèles de conception

坏嘻嘻
坏嘻嘻original
2018-09-14 09:45:021626parcourir

Ce tutoriel vous expliquera le concept de modèles de conception étape par étape à travers des exemples Java.

1. Principe de responsabilité unique

Objectif : Réduire la complexité du code, découpler le système et améliorer la lisibilité

Signification : Pour une classe, il n'y a qu'une seule raison pour le changement de classe ; la responsabilité de la classe est unique, et cette responsabilité est la seule raison pour le changement des autres classes.

Solution : Encapsulez différentes responsabilités dans différentes classes ou modules. Lorsqu’il existe de nouvelles exigences qui divisent les responsabilités existantes en responsabilités plus petites, le code existant doit être remanié en temps opportun. Lorsque la logique du système est suffisamment simple, les méthodes sont suffisamment peu nombreuses, les sous-classes sont suffisamment peu nombreuses ou les associations ultérieures sont suffisamment peu nombreuses, vous n'êtes pas obligé de suivre strictement vos principes SRP pour éviter une conception excessive et une granularité excessive.

Exemple : Le type de fil Wire alimente les résidents avec une tension de 220 V. Cependant, de nouvelles demandes augmentent et les fils transportent également de l'électricité à haute tension avec une tension de 200 kV. Le type de fil d'origine peut être implémenté en ajoutant des méthodes Expansion, ce qui viole le principe de responsabilité unique. Vous pouvez fournir une classe de base et créer deux classes dérivées : les lignes d'alimentation électrique résidentielles et les lignes de transmission haute tension.

2. Principe de substitution de Liskov

Objectif : Éviter la destruction du système d'héritage du système

Signification : Toutes les références à une classe de base doit pouvoir utiliser de manière transparente les objets de ses sous-classes.

Solution : Une sous-classe peut implémenter la méthode abstraite de la classe parent, mais ne peut pas remplacer la méthode non abstraite de la classe parent ; la sous-classe peut ajouter ses propres méthodes uniques ; la sous-classe remplace ou implémente Lorsque la méthode de la classe parent est une méthode, les conditions préalables de la méthode (c'est-à-dire les paramètres formels de la méthode) sont plus souples que les paramètres d'entrée de la méthode de la classe parent lorsque la méthode de la sous-classe implémente l'abstrait ; méthode de la classe parent, les postconditions de la méthode (c'est-à-dire la valeur de retour de la méthode) sont plus strictes que celles de la classe parent. Si la sous-classe ne peut pas implémenter complètement les méthodes de la classe parent, ou si certaines méthodes de la classe parent ont été déformées dans la sous-classe, il est recommandé de déconnecter la relation d'héritage et d'utiliser la dépendance, l'agrégation, la combinaison et d'autres relations au lieu de l'héritage.

Exemple : La méthode permettant aux oiseaux de voler avec deux ailes a été définie ; l'autruche nouvellement ajoutée ne peut pas voler. Si vous remplacez la méthode de la classe parent, ce qu'il y a dans la méthode. voler avec deux ailes ? Si vous ne le faites pas, vous violerez le principe de substitution de Richter et empêcherez tous les oiseaux de voler. Deux classes de base d'oiseaux devraient être créées côte à côte, volantes et incapables de voler. Les préconditions sont plus souples et les postconditions sont plus strictes. Par exemple, la classe parent renvoie Map et la sous-classe renvoie HashMap ; la classe parent accepte les paramètres formels HashMap et la sous-classe accepte Map.

3. Principe d'inversion des dépendances

Objectif : Éviter les travaux de maintenance excessifs causés par les changements d'exigences

Signification : Élevé- les modules de niveau ne doivent pas dépendre de modules de bas niveau, les deux doivent dépendre de leurs abstractions ; les abstractions ne doivent pas dépendre des détails ;

Solution : Programmation orientée interface, utiliser des interfaces ou des classes abstraites pour formuler des spécifications et des contrats sans impliquer d'opérations spécifiques, et laisser la tâche de montrer les détails à leurs classes d'implémentation Terminer.

Exemple : La classe mère Mother a une méthode de narration TellStory, qui s'appuie sur une entrée de classe Book et utilise la méthode getContent de la classe Book pour raconter des histoires. Ensuite, la prochaine fois que vous aurez besoin que votre mère raconte des histoires à partir de journaux ou de téléphones portables, l'interface d'origine sera impuissante. À l'heure actuelle, une classe de base IReader contenant la méthode getContent est abstraite et Book, Newspaper et Cellphone sont implémentés séparément. La méthode TellStory de la mère accepte une instance IReader et appelle la méthode getContent.

4. Principe de ségrégation des interfaces

Objectif : Éviter les interfaces gonflées

Signification : Client Il ne doit pas s'appuyer sur des interfaces qui ce n'est pas nécessaire. La dépendance d'une classe à l'égard d'une autre classe doit être basée sur la plus petite interface.

Solution : Affiner modérément l'interface et diviser l'interface gonflée en plusieurs interfaces indépendantes.

Exemple : Interface d'examen, comprenant des méthodes pour tester la langue, les mathématiques, la physique, la chimie, la biologie, la politique, l'histoire, la géographie, etc. La classe d'étudiants implémente l'interface d'examen et passe l'examen. La classe d'étudiants en arts libéraux et la classe d'étudiants en sciences sont dérivées de la classe d'étudiants. Lors de la mise en œuvre de l'interface d'examen, ils doivent implémenter certaines méthodes dont ils n'ont pas besoin (car les étudiants en arts libéraux ne passent pas l'examen de physique et de chimie, ni les examens de sciences). les étudiants ne passent pas l’examen de politique, d’histoire et de géographie). À l'heure actuelle, l'interface d'examen doit être affinée et divisée en interface d'examen de matière de base, interface d'examen d'arts libéraux et interface d'examen de sciences ; interface d'examen.

5. Principe de Déméter

Objectif : Réduire le couplage entre les classes

Signification : Chaque unité logicielle a une connaissance minimale des autres unités et est limitée aux unités logicielles qui sont étroitement liées à sa propre unité.

Solution : Les classes inconnues qui n'ont pas de relations de couplage telles que dépendance, association, combinaison, agrégation, etc. ne doivent pas apparaître à l'intérieur de la classe en tant que variables locales.

Exemple : Le directeur gère les enseignants, et les enseignants gèrent les élèves. Lorsque le directeur a besoin d'appeler tout le monde, il doit d'abord appeler les enseignants. Cependant, il n'est pas nécessaire d'obtenir les informations sur les élèves et de procéder à l'appel par l'intermédiaire des enseignants. Les enseignants doivent plutôt être autorisés à gérer l'appel des élèves. Sinon, des couplages inutiles se produiront entre le directeur et les élèves. Lorsque la classe d'élèves change, la classe du professeur et la classe du directeur doivent être modifiées.

6. Principe de réutilisation composite

Objectif : Empêcher le système de classes de devenir énorme

Signification : Lors de l'extension des fonctionnalités d'une classe, privilégiez la composition/agrégation à l'héritage.

Solution : Lorsque la relation entre les classes est "Est-A", utilisez l'héritage ; lorsque la relation entre les classes est "Has-A", utilisez la combinaison.

Exemple : Par exemple, en mode pont, l'abstraction et l'implémentation peuvent être modifiées indépendamment. Lors de l'extension des fonctions, ajoutez simplement des classes d'implémentation. Par exemple, en mode décoration, une seule classe est nécessaire. pour former une classe. Les classes étendent de nouvelles fonctionnalités. Pour les exigences d’affichage graphique, utilisez la classe Graphics Shape et la classe Display Paint pour les implémenter. Chaque classe Shape possède un pointeur de classe Paint responsable du dessin et de l’affichage des graphiques. La classe Paint dérive la classe RedPaint et la classe BluePaint et les transmet à la classe Shape pour réaliser le dessin de graphiques dans différentes couleurs, de sorte que la logique de dessin graphique et l'implémentation du dessin graphique puissent être modifiées indépendamment. Un jour, la demande augmente et tous les dessins doivent ajouter des bordures. Vous pouvez ajouter la classe PaintDecorator, qui est dérivée de la classe de base Paint. Chaque classe PaintDecorator possède un pointeur d'objet Paint. Ajoutez la fonction virtuelle AddedPaint, réécrivez la méthode de dessin Paint. et ajoutez l'appel à la méthode AddedPaint. Ajoutez la classe BorderPaintDecorator, qui est dérivée de la classe PaintDecorator, remplace la méthode AddedPaint et ajoute le code pour dessiner la bordure. De cette façon, l’ajout d’une nouvelle classe peut étendre les fonctions de toutes les classes de pinceaux d’origine.

7. Principe d'ouverture et de fermeture

Objectif : Améliorer l'évolutivité et faciliter la maintenance

Signification : Ouvert pour extension, fermé pour modification. Autrement dit, l'expansion du système est encouragée, mais la modification du code système existant n'est pas prise en charge. En d’autres termes, lorsque le logiciel a de nouvelles exigences et changements, il suffit d’étendre le framework logiciel pour s’adapter aux nouvelles exigences, plutôt que de modifier le code dans le framework.

Solution : Les 6 premiers principes des modèles de conception et les 23 modèles de conception sont bien suivis, et le principe d'ouverture et de fermeture est naturellement bien suivi. En restant tourné vers l'avenir et prévisible quant à l'évolution des exigences, l'abstraction peut être rendue plus largement applicable et l'architecture logicielle conçue peut être relativement stable. Les détails variables dans les exigences logicielles sont étendus en dérivant des classes d'implémentation à partir d'abstractions.

Joindre : Exemple de code du principe de réutilisation de synthèse, utilisant le mode pont et le mode décoration en combinaison

#include <iostream>

//绘制类
class Paint
{
public:
	virtual void Draw() = 0;
};

//红色绘制类
class RedPaint : public Paint
{
public:
	void Draw()
	{
		std::cout << "Color Red!" << std::endl;
	}
};

//蓝色绘制类
class BluePaint : public Paint
{
public:
	void Draw()
	{
		std::cout << "Color Blue!" << std::endl;
	}
};

//图形类,使用桥接模式,将图形绘制逻辑与绘制实现解耦
class Shape
{
public:
	Shape(Paint* pt) : m_pPt(pt)
	{	 
	}

	virtual void Show()
	{
		std::cout << "Shape Style:" << std::endl;
		m_pPt->Draw();
	}

protected:
	Paint* m_pPt;
};


//长方形类
class Rectangle : public Shape
{
public:
	Rectangle(Paint* pt) : Shape(pt)
	{
	}
};

//圆形类
class Circle : public Shape
{
public:
	Circle(Paint* pt) : Shape(pt)
	{

	}
};

//附加绘制类,使用装饰模式,对原有绘制类进行功能扩展
class PaintDecorator : public Paint
{
public:
	PaintDecorator(Paint* pt) : m_pPt(pt) { }
	
	void Draw()
	{
		m_pPt->Draw();
		AddedPaint();
	}
	virtual void AddedPaint() = 0;

protected:
	Paint* m_pPt;
};

//附加边框类,对绘制类添加边框绘制功能
class BoarderDecorator : public PaintDecorator
{
public:
	BoarderDecorator(Paint* pt) : PaintDecorator(pt)
	{
	}

	void AddedPaint()
	{
		std::cout << "With Boarder!" << std::endl;
	}
};

void main()
{
	Shape* pShape = new Circle(new BoarderDecorator(new RedPaint()));
	pShape->Show();

	return;
}

Recommandations associées :

JavaScript Design Pattern Factory Pattern et compétences du constructeur pattern_javascript

Une étude préliminaire sur les compétences des modèles de conception JavaScript_javascript

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn