Cet article fournit un aperçu clair et concis des principes de conception SOLID, accompagné d'exemples de code simples pour vous aider à comprendre facilement chaque concept.
SOLID est un ensemble de cinq principes de conception destinés à rendre les conceptions logicielles plus compréhensibles, flexibles et maintenables.
Les principes sont particulièrement utiles dans la conception orientée objet et sont couramment appliqués dans le développement front-end et back-end. Voici un bref aperçu de chaque principe SOLID avec un exemple de code en TypeScript :
Une classe devrait avoir une et une seule raison de changer, ce qui signifie qu'elle ne devrait avoir qu'un seul travail ou responsabilité.
Ce principe encourage une approche ciblée, garantissant que les modifications ou mises à jour apportées à un aspect de votre interface utilisateur n'affecteront pas par inadvertance des parties non liées.
// UserProfile.tsx import React from 'react'; interface UserProfileProps { username: string; email: string; } const UserProfile: React.FC<UserProfileProps> = ({ username, email }) => { return ( <div> <h2>{username}</h2> <p>{email}</p> </div> ); }; export default UserProfile;
Ici, UserProfile est uniquement responsable de l'affichage des informations utilisateur.
Les entités logicielles doivent être ouvertes pour extension mais fermées pour modification.
Cette approche garantit que les composants principaux restent stables et inchangés, réduisant ainsi le risque d'effets secondaires involontaires lors de l'ajout de nouvelles fonctionnalités.
// Alert.tsx import React from 'react'; interface AlertProps { message: string; } const Alert: React.FC<AlertProps> = ({ message }) => { return <div className="alert">{message}</div>; }; export default Alert; // SuccessAlert.tsx import React from 'react'; import Alert from './Alert'; const SuccessAlert: React.FC<{ message: string }> = ({ message }) => { return <Alert message={`Success: ${message}`} />; }; export default SuccessAlert;
L'alerte peut être étendue par SuccessAlert sans modifier le composant Alert d'origine.
Les objets d'une superclasse doivent être remplaçables par des objets de ses sous-classes sans affecter l'exactitude du programme.
En termes plus simples, si vous disposez d'un composant ou d'un module de base, tous les composants dérivés doivent être utilisables à la place du composant de base sans provoquer de problèmes inattendus.
// BaseButton.tsx import React from 'react'; interface BaseButtonProps { onClick: () => void; label: string; } const BaseButton: React.FC<BaseButtonProps> = ({ onClick, label }) => { return <button onClick={onClick}>{label}</button>; }; export default BaseButton; // IconButton.tsx import React from 'react'; import BaseButton from './BaseButton'; interface IconButtonProps extends BaseButtonProps { icon: string; } const IconButton: React.FC<IconButtonProps> = ({ onClick, label, icon }) => { return ( <BaseButton onClick={onClick} label={<span><i className={icon}></i> {label}</span>} /> ); }; export default IconButton;
IconButton peut être utilisé n'importe où BaseButton sans affecter l'exactitude de l'application.
Aucun client ne devrait être obligé de dépendre de méthodes qu’il n’utilise pas. Cela signifie créer des interfaces spécifiques pour des besoins spécifiques.
En d'autres termes, plutôt que de créer une seule grande interface, divisez-la en interfaces plus petites et ciblées, adaptées aux composants individuels.
// interfaces.ts export interface Flyable { fly(): void; } export interface Swimmable { swim(): void; } // Bird.ts import { Flyable } from './interfaces'; class Bird implements Flyable { fly() { console.log('Bird is flying'); } } // Fish.ts import { Swimmable } from './interfaces'; class Fish implements Swimmable { swim() { console.log('Fish is swimming'); } }
Des interfaces distinctes Flyable et Swimmable sont créées pour garantir que les classes n'implémentent que ce dont elles ont besoin.
Les modules de haut niveau ne doivent pas dépendre de modules de bas niveau mais d'abstractions. Les deux devraient dépendre d’abstractions.
En termes plus simples, au lieu de composants dépendant directement les uns des autres, ils s'appuient sur des interfaces ou des classes abstraites, rendant le code plus adaptable aux changements.
// Logger.ts export interface Logger { log(message: string): void; } export class ConsoleLogger implements Logger { log(message: string) { console.log(message); } } // UserService.ts import { Logger } from './Logger'; class UserService { constructor(private logger: Logger) {} createUser(username: string) { this.logger.log(`User created: ${username}`); } } // App.ts import { UserService } from './UserService'; import { ConsoleLogger } from './Logger'; const logger = new ConsoleLogger(); const userService = new UserService(logger); userService.createUser('JohnDoe');
Ici, UserService dépend de l'abstraction Logger, ce qui permet de modifier le mécanisme de journalisation sans altérer UserService.
Ces principes SOLID aident à créer des logiciels faciles à maintenir, à étendre et à refactoriser, ce qui est essentiel pour développer des applications front-end et back-end robustes.
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!