Когда я впервые начал погружаться в мир разработки программного обеспечения, меня часто ошеломляло множество модных словечек и концепций, которые летали вокруг. Одной из концепций, которая казалась особенно сложной, были принципы SOLID. Казалось, что о чем-то должны беспокоиться только «серьезные» разработчики. Но по мере того, как я стал чувствовать себя более комфортно в программировании, я понял, что эти принципы заключаются не столько в фантазии, сколько в написании кода, который не вызывает у вас желания рвать на себе волосы через несколько месяцев.
Итак, вот мой взгляд на принципы SOLID в JavaScript — серьезное практическое руководство, которое мне хотелось бы иметь, когда я только начинал.
Принцип единой ответственности гласит, что у класса должна быть только одна причина для изменения, то есть у него должна быть только одна работа или ответственность.
Представьте себе бариста в вашей любимой кофейне. Их работа – готовить кофе. Если им вдруг придется начать ремонтировать кофемашину, подавать выпечку и выносить мусор, все станет хаотичным. Точно так же, как бариста должен сосредоточиться на приготовлении кофе, ваш класс должен сосредоточиться на том, чтобы хорошо делать что-то одно.
Представьте, что у вас есть класс User, который занимается аутентификацией пользователей, проверкой данных и хранением базы данных. Это делает слишком много! Разделив эти обязанности на отдельные классы, вы упрощаете управление и поддержку своего кода.
class UserAuthenticator { login(user) { // handle login } } class UserDataValidator { validate(user) { // validate user data } } class UserDatabase { save(user) { // save user to the database } }
Принцип открытости/закрытости гласит, что программные объекты должны быть открыты для расширения, но закрыты для модификации. Другими словами, у вас должна быть возможность добавлять новые функции без изменения существующего кода.
Представьте себе свою любимую игровую консоль. Вы можете добавлять новые игры, контроллеры и аксессуары, но вам не нужно для этого открывать его и переподключать. Точно так же вы сможете добавлять новые функции в свой код, не меняя его основную структуру.
Предположим, у вас есть класс Shape с методом вычисления площади. Если вам нужно добавить новую фигуру, например треугольник, вам не нужно изменять существующий класс. Вместо этого расширьте его.
class Shape { area() { throw "Area method not implemented"; } } class Rectangle extends Shape { constructor(width, height) { super(); this.width = width; this.height = height; } area() { return this.width * this.height; } } class Circle extends Shape { constructor(radius) { super(); this.radius = radius; } area() { return Math.PI * this.radius * this.radius; } }
Принцип замены Лискова гласит, что объекты суперкласса должны быть заменены объектами подкласса без ущерба для корректности программы.
Представьте, что вы арендуете автомобиль. Независимо от того, покупаете ли вы седан или внедорожник, вы ожидаете, что он будет обладать основными функциями автомобиля: он должен ехать, управлять и останавливаться. Если бы для вашего арендованного автомобиля требовался совершенно другой набор элементов управления, у вас были бы проблемы! Точно так же подклассы должны вести себя так, чтобы не нарушать ожидания, установленные их родительским классом.
Если у вас есть класс Bird и расширяющий его класс Penguin, Penguin все равно должен вести себя как Bird, даже если он не умеет летать. Он все равно должен ходить, есть и, возможно, даже плавать.
class Bird { move() { console.log("Flies in the sky"); } } class Penguin extends Bird { move() { console.log("Swims in the water"); } } const myBird = new Bird(); const myPenguin = new Penguin(); myBird.move(); // Flies in the sky myPenguin.move(); // Swims in the water
Принцип разделения интерфейсов предполагает, что клиентов не следует заставлять реализовывать интерфейсы, которые они не используют. Вместо одного большого интерфейса вам следует создавать более мелкие и конкретные интерфейсы.
Представьте себе ресторан, где шеф-повару приходится одновременно быть официантом, барменом и посудомойщиком. Это слишком сложно и неэффективно! Вместо этого каждая роль должна иметь свои конкретные задачи. Точно так же ваши интерфейсы должны быть специализированными и целенаправленными.
Если у вас есть интерфейс Worker, включающий такие методы, как buildHouse, PaintHouse и designHouse, работнику, который только красит дома, не нужно реализовывать все остальные методы. Разбейте его на более мелкие интерфейсы.
class Builder { build() { console.log("Building house..."); } } class Painter { paint() { console.log("Painting house..."); } } class Designer { design() { console.log("Designing house..."); } }
Принцип инверсии зависимостей гласит, что модули высокого уровня не должны зависеть от модулей низкого уровня. Оба должны зависеть от абстракций.
Подумайте о том, как вы подключаете зарядное устройство телефона к сетевой розетке. Вам не нужно знать подробности электропроводки внутри стен — все, что вам нужно, это интерфейс (розетка) для питания вашего устройства. Точно так же ваш код должен зависеть от абстракций (интерфейсов), а не от конкретных реализаций.
Если у вас есть класс LightBulb, который напрямую управляет классом Switch, вы создаете тесную связь. Вместо этого оба должны зависеть от такого интерфейса, как PowerSource.
class LightBulb { turnOn(powerSource) { powerSource.provideElectricity(); console.log("Light is on"); } } class Switch { constructor(powerSource) { this.powerSource = powerSource; } operate() { this.powerSource.togglePower(); } } class PowerSource { provideElectricity() { console.log("Providing electricity"); } togglePower() { console.log("Toggling power"); } }
Освоение принципов SOLID похоже на обучение приготовлению пищи по проверенным рецептам. Поняв их, вы сможете создавать код, который будет не просто функциональным, но элегантным и простым в сопровождении. Так что в следующий раз, когда вы столкнетесь с загадкой кодирования, помните: для этого есть принцип!
Удачного программирования! ?
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3