Обновление
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Struchkov Mark 2024-09-27 20:25:32 +03:00
parent ef88b1c6db
commit 1536a6c68c
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
31 changed files with 772 additions and 29 deletions

View File

@ -0,0 +1,74 @@
---
aliases:
- DIP
- Принцип инверсии зависимостей
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[SOLID|SOLID]]"
linked:
---
Высокоуровневые модули не должны зависеть от низкоуровневых модулей. Оба должны зависеть от абстракций. Это означает, что классы не должны напрямую зависеть от конкретных реализаций, вместо этого они должны работать с абстракциями (интерфейсами или абстрактными классами). Это делает код гибким и легко расширяемым.
- **Пример нарушения DIP**: Высокоуровневый модуль напрямую использует конкретный класс, что приводит к жёсткой связности.
- **Решение**: Заменить зависимости на интерфейсы и внедрять зависимости через инверсии (например, через конструктор или контейнеры зависимостей).
```java
public class Lamp {
public void turnOn() {
// Лампа включена
}
}
public class Switch {
private Lamp lamp;
public Switch(Lamp lamp) {
this.lamp = lamp;
}
public void toggle() {
lamp.turnOn(); // Нарушение DIP — жесткая зависимость от класса Lamp
}
}
```
Исправление с использованием интерфейсов:
```java
public interface Switchable {
void turnOn();
}
public class Lamp implements Switchable {
public void turnOn() {
// Лампа включена
}
}
public class Switch {
private Switchable device;
public Switch(Switchable device) {
this.device = device;
}
public void toggle() {
device.turnOn(); // Теперь зависимость инверсирована — Switch зависит от абстракции
}
}
```
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[SOLID]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,56 @@
---
aliases:
- ISP
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[SOLID|SOLID]]"
linked:
---
Лучше создавать несколько специализированных интерфейсов, чем один универсальный интерфейс, который вынуждает реализовать ненужные методы. Каждый интерфейс должен описывать только те действия, которые будут использоваться конкретным клиентом.
- **Пример нарушения ISP**: Один интерфейс заставляет классы реализовывать методы, которые они не используют.
- **Решение**: Разделить интерфейс на несколько специализированных.
```java
public interface Worker {
void work();
void eat();
}
public class RobotWorker implements Worker {
public void work() {
// Робот работает
}
public void eat() {
// Робот не ест — нарушение ISP
}
}
```
Можно разделить интерфейсы:
```java
public interface Worker {
void work();
}
public interface Eater {
void eat();
}
```
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[SOLID]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,45 @@
---
aliases:
- LSP
- Принцип подстановки Барбары Лисков
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../garden/ru/meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[SOLID|SOLID]]"
linked:
---
Объекты подкласса должны быть взаимозаменяемы с объектами базового класса без нарушения поведения программы. Это значит, что подклассы не должны изменять базовую логику родительских классов или нарушать их контракт.
- **Пример нарушения LSP**: Подкласс переопределяет методы родительского класса, изменяя их поведение, что приводит к непредсказуемым результатам при работе с кодом через базовый класс.
- **Решение**: Подклассы должны следовать контракту базового класса, не нарушая его поведение.
```java
public class Bird {
public void fly() {
// Птица летает
}
}
public class Penguin extends Bird {
@Override
public void fly() {
// Пингвин не может летать — нарушение LSP
}
}
```
Вместо этого можно выделить разные классы для летающих и нелетающих птиц, чтобы избежать нарушения принципа подстановки.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[SOLID]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,51 @@
---
aliases:
- Open/Closed Principle
- OCP
- Принцип открытости/закрытости
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[SOLID|SOLID]]"
linked:
---
Классы должны быть открыты для расширения, но закрыты для модификации. Это значит, что поведение класса можно расширить без изменения его исходного кода. Обычно это достигается через наследование или использование интерфейсов.
- **Пример нарушения OCP**: Изменение существующего класса для добавления нового функционала (например, новый способ оплаты).
- **Решение**: Использовать интерфейсы или абстрактные классы для расширения функционала без изменения базового кода.
```java
public interface PaymentMethod {
void pay(double amount);
}
public class CreditCardPayment implements PaymentMethod {
@Override
public void pay(double amount) {
// Оплата через кредитную карту
}
}
public class PayPalPayment implements PaymentMethod {
@Override
public void pay(double amount) {
// Оплата через PayPal
}
}
```
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[SOLID|SOLID]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

42
dev/architecture/SOLID.md Normal file
View File

@ -0,0 +1,42 @@
---
aliases:
- S.O.L.I.D.
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
linked:
---
**SOLID** — это набор из пяти принципов объектно-ориентированного проектирования, предложенных Робертом Мартином (Robert C. Martin), которые помогают создавать более понятные, гибкие и поддерживаемые системы. Эти принципы направлены на улучшение структуры кода и снижение его сложности, что упрощает расширение и поддержку проекта.
- [[Single Responsibility Principle]]
- [[Open Closed Principle|Open/Closed Principle]]
- [[Liskov Substitution Principle]]
- [[Interface Segregation Principle]]
- [[Dependency Inversion Principle]]
> [!WARNING] Недостижимый идеал
> Важно не применять принципы слепо, а учитывать контекст проекта и потребности системы. SOLID это идеал, к которому стоит стремиться, но который не достижим в реальной жизни.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Open Closed Principle]]
- [[Liskov Substitution Principle]]
- [[Single Responsibility Principle]]
- [[Interface Segregation Principle]]
- [[Dependency Inversion Principle]]
<!-- SerializedQuery END -->

View File

@ -0,0 +1,42 @@
---
aliases:
- SRP
- принцип единственной ответственности
- Single Responsibility
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../garden/ru/meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[SOLID|SOLID]]"
linked:
---
Каждый класс должен иметь только одну ответственность, или одну причину для изменения. Это означает, что класс должен выполнять лишь одну задачу или представлять один аспект системы.
- **Пример нарушения SRP**: Класс, который одновременно управляет данными пользователя и отправкой сообщений по электронной почте.
- **Решение**: Разделить задачи на два отдельных класса — один для управления пользователем, другой для работы с уведомлениями.
```java
public class UserService {
// Только управление пользователем
}
public class EmailService {
public void sendEmail(String email, String message) {
// Только отправка сообщений
}
}
```
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[SOLID]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -35,3 +35,6 @@ linked:
- [[Вертикальное масштабирование]] - [[Вертикальное масштабирование]]
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[garden/ru/dev/architecture/highload/Репликация.md|Репликация]]
<!-- SerializedQuery END -->

View File

@ -44,6 +44,3 @@ linked:
- [[Кэширование статики в Nginx]] - [[Кэширование статики в Nginx]]
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Fingerprint]]
<!-- SerializedQuery END -->

View File

@ -85,16 +85,16 @@ linked:
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Асинхронная репликация]]
- [[Безмастерная репликация]]
- [[Групповая репликация]]
- [[Монотонное чтение]]
- [[Отставание реплики БД]]
- [[Полу-синхронная репликация]]
- [[Репликация master-master]]
- [[Репликация master-slave]]
- [[Синхронная репликация]]
- [[Согласованное префиксное чтение]] - [[Согласованное префиксное чтение]]
- [[Репликация в MySQL]] - [[Репликация в MySQL]]
- [[Репликация в PostgreSQL]] - [[Репликация в PostgreSQL]]
- [[Репликация master-slave]]
- [[Репликация master-master]]
- [[Безмастерная репликация]]
- [[Синхронная репликация]]
- [[Асинхронная репликация]]
- [[Полу-синхронная репликация]]
- [[Отставание реплики БД]]
- [[Монотонное чтение]]
- [[Групповая репликация]]
<!-- SerializedQuery END --> <!-- SerializedQuery END -->

View File

@ -0,0 +1,46 @@
---
aliases:
- архитектурного слоя
- слой
- слоями
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
linked:
---
Архитектурный слой — это уровень абстракции, который разделяет систему на части (слои), обеспечивая логическую организацию компонентов. Каждый слой отвечает за выполнение конкретных задач и взаимодействует с другими слоями через четко определённые интерфейсы.
Пример классической многослойной архитектуры — это разделение на уровни представления (интерфейс пользователя), бизнес-логики (основные процессы) и данных (хранение и управление информацией). Это облегчает разработку, поддержку и масштабирование системы.
Основные идеи использования слоёв в архитектуре:
- **Чёткое разделение ответственности (Separation of Concerns)**: Каждый слой должен быть сосредоточен на выполнении одной задачи (например, UI, бизнес-логика, доступ к данным). Например, слой бизнес-логики не должен заниматься задачами, связанными с пользовательским интерфейсом, и наоборот. Это упрощает изменения, поддержку и тестирование.
- **Минимизация связности между слоями**: Взаимодействие между слоями должно происходить через хорошо определённые интерфейсы или API. Это снижает зависимость слоёв друг от друга и облегчает замену или обновление слоёв.
- **Инверсия зависимостей**: Верхние слои не должны зависеть от реализации нижних слоёв. Использование абстракций (интерфейсов) помогает избежать жестких зависимостей и улучшает тестируемость.
- **Логика не должна просачиваться между слоями**: Каждая бизнес-логика или специфическая реализация должны быть строго в том слое, к которому они относятся, чтобы избежать смешивания задач.
- **Использование принципов** [[SOLID|SOLID]]: Следование принципам объектно-ориентированного проектирования, таким как единая ответственность ([[Single Responsibility Principle|Single Responsibility]]) и открытость/закрытость ([[Open Closed Principle|Open/Closed Principle]]), помогает создать гибкие и легко расширяемые архитектуры.
Преимущества:
- **Модульность**: Легче модифицировать или заменять части системы без влияния на весь код.
- **Повторное использование**: Логика, размещённая в одном слое, может быть использована различными частями системы.
- **Упрощение тестирования**: Благодаря разделению задач, тестирование может быть сосредоточено на отдельных слоях.
Частые ошибки:
- **Слои как простая формальность**: Иногда разработчики создают слои, но не используют их как абстракции. Это приводит к тому, что слои теряют свой смысл и становятся перегруженными логикой, не относящейся к их роли.
- **Слишком много слоёв**: Перегруженная многослойная архитектура может стать трудной для понимания и сопровождения. Использование слишком большого количества слоёв увеличивает сложность без явных преимуществ.
- [[Необоснованное использование ORM в слое бизнес-логики]]: Когда объекты из слоя данных (например, сущности ORM) напрямую используются в бизнес-слое, это нарушает принцип [[Инкапсуляция|инкапсуляции]] и ведёт к избыточным зависимостям.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,62 @@
---
aliases:
- инкапсуляцию
- инкапсуляции
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[../garden/ru/dev/architecture/ООП|ООП]]"
linked:
---
Инкапсуляция — один из ключевых принципов [[ООП|объектно-ориентированного программирования]] (ООП), который обеспечивает контроль доступа к данным и методам объекта, скрывая внутреннюю реализацию и предоставляя только необходимые интерфейсы для взаимодействия с внешним миром.
Основные идеи инкапсуляции:
- **Сокрытие данных**: Внутренние детали реализации объекта, такие как его состояние или внутренние методы, не должны быть доступны напрямую из внешнего кода. Это позволяет избежать прямого изменения данных объекта извне и защищает его от некорректного использования.
- **Чёткие интерфейсы**: Объект предоставляет только те методы и свойства, которые необходимы для работы с ним, скрывая всю сложную внутреннюю логику. Это упрощает работу с объектом и делает его использование безопасным.
- **Управляемое изменение состояния**: Изменение состояния объекта происходит через методы, которые контролируют корректность этих изменений и могут проводить валидацию, логику или вызовы других методов.
Частые ошибки:
- **Избыточная доступность**: Если данные и методы не скрыты должным образом, это приводит к увеличению связности компонентов и нарушению принципа инкапсуляции.
- **Смешивание ответственности**: Когда внутренние данные объекта предоставляются другим компонентам, появляется риск того, что ответственность за управление состоянием будет распределена между разными частями системы.
## Пример инкапсуляции
Представьте, что у вас есть объект `BankAccount`, который хранит баланс пользователя. Чтобы обеспечить безопасность, прямой доступ к балансу невозможен. Вместо этого объект предоставляет методы `deposit()` и `withdraw()`, которые корректно изменяют баланс и проверяют возможность транзакции:
```java
public class BankAccount {
private double balance;
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
}
}
public void withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
}
}
public double getBalance() {
return balance;
}
}
```
Таким образом, инкапсуляция помогает управлять состоянием объекта, делая его использование безопасным и устойчивым к ошибкам.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[ООП]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -40,7 +40,7 @@ linked:
Чаще всего кэш реализуется на основе [[../fundamental/structure/Хеш-таблица|хеш-таблиц]] и использует [принцип локальности](../fundamental/Принцип%20локальности.md). Для работы с хеш-таблицей вам необходим [[highload/Ключ кэширования|ключ кэширования]] и сами данные. По ключу данные кладутся и забираются из таблицы. Чаще всего кэш реализуется на основе [[../fundamental/structure/Хеш-таблица|хеш-таблиц]] и использует [принцип локальности](../fundamental/Принцип%20локальности.md). Для работы с хеш-таблицей вам необходим [[highload/Ключ кэширования|ключ кэширования]] и сами данные. По ключу данные кладутся и забираются из таблицы.
Для хранения результатов кэширования я обычно использую JSON. Использую для этого библиотеку [[../../../../knowledge/dev/java/other/Jackson|Jackson]], но есть один [[../../../../_inbox/Преобразование Json из коллекции в Java объект при помощи Jackson|нюанс при работе с коллекциям]], который стоит учитывать. Для хранения результатов кэширования я обычно использую JSON. Использую для этого библиотеку [[../../../../knowledge/dev/java/other/Jackson|Jackson]], но есть один [[../snippet/Преобразование Json из коллекции в Java объект при помощи Jackson|нюанс при работе с коллекциям]], который стоит учитывать.
При желании результат кэширования можно сжать используя [[../algorithm/GZIP|GZIP]]. Однако, приходится использовать [[../other/Base64|Base64]], чтобы преобразовать байты полученные от gzip в строку, и уже в таком виде положить в Redis. Не смотря на то, что Base64 увеличивает размер строки на 33% все равно получается намного компактнее, чем просто JSON. При желании результат кэширования можно сжать используя [[../algorithm/GZIP|GZIP]]. Однако, приходится использовать [[../other/Base64|Base64]], чтобы преобразовать байты полученные от gzip в строку, и уже в таком виде положить в Redis. Не смотря на то, что Base64 увеличивает размер строки на 33% все равно получается намного компактнее, чем просто JSON.

View File

@ -0,0 +1,31 @@
---
aliases:
- объектно-ориентированного программирования
- объектно ориентированного программирования
- объектно ориентированное программирование
- объектно-ориентированное программирование
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
linked:
---
- [[Полиморфизм]]
- [[Инкапсуляция|Инкапсуляция]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Полиморфизм]]
<!-- SerializedQuery END -->

View File

@ -0,0 +1,130 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[ООП]]"
linked:
---
Полиморфизм — это один из фундаментальных принципов [[ООП|объектно-ориентированного программирования]] (ООП), который позволяет объектам разных классов обрабатывать одно и то же сообщение (вызов метода) по-разному. Это делает код более гибким и расширяемым, упрощая добавление новых возможностей без изменения существующего кода.
## Основные виды полиморфизма
**Полиморфизм времени компиляции (статический)**: Это форма полиморфизма, которая определяется на этапе компиляции программы. Примеры включают **перегрузку методов** и **перегрузку операторов**.
Один и тот же метод может иметь несколько версий, которые различаются по количеству или типам параметров.
Пример перегрузки метода:
```java
public class MathOperations {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
```
**Полиморфизм времени выполнения (динамический)**: Это форма полиморфизма, которая проявляется на этапе выполнения программы. Здесь используется **наследование** и **переопределение методов**.
Полиморфизм времени выполнения позволяет классу, наследующему методы базового класса, предоставлять свою собственную реализацию этих методов.
Пример динамического полиморфизма:
```java
public class Animal {
public void makeSound() {
System.out.println("Animal makes sound");
}
}
public class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
public class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // Полиморфизм
myAnimal.makeSound(); // Вывод: Dog barks
myAnimal = new Cat();
myAnimal.makeSound(); // Вывод: Cat meows
}
}
```
## Преимущества полиморфизма
- **Гибкость кода**: Полиморфизм позволяет работать с объектами через абстракции (интерфейсы или базовые классы), что делает систему гибкой для расширений и изменений. Например, новый класс может быть добавлен без изменения существующих классов или логики.
- **Упрощённое управление**: Код становится более управляемым и понятным, поскольку можно использовать общие типы данных (например, интерфейсы) для работы с разными реализациями.
- **Повторное использование кода**: Полиморфизм способствует использованию общих базовых классов, что уменьшает дублирование и увеличивает повторное использование кода.
## Частые ошибки при использовании полиморфизма
- **Избыточное использование полиморфизма**: Когда полиморфизм используется там, где он не нужен, это может усложнить код. Например, создание слишком большого количества наследников для решения простой задачи.
- **Нарушение принципа подстановки Лисков**: Это принцип гласит, что объект подкласса должен корректно заменять объект родительского класса без изменения поведения программы. Если полиморфизм реализован неправильно, это может привести к неожиданным ошибкам.
- **Неправильное управление зависимостями**: Если базовые классы слишком зависят от подклассов или знают о специфике их реализации, это может разрушить архитектуру. Полиморфизм должен использоваться вместе с инверсией зависимостей для минимизации связности.
## Пример полиморфизма
Представьте, что у вас есть система для обработки платежей, которая поддерживает разные способы оплаты: кредитные карты, PayPal, банковские переводы. В этом случае вы можете создать абстрактный класс или интерфейс `PaymentMethod`, а затем реализовать его для каждого конкретного метода оплаты:
```java
public interface PaymentMethod {
void pay(double amount);
}
public class CreditCard implements PaymentMethod {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " with Credit Card");
}
}
public class PayPal implements PaymentMethod {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " with PayPal");
}
}
public class PaymentProcessor {
public void processPayment(PaymentMethod method, double amount) {
method.pay(amount);
}
}
public class Main {
public static void main(String[] args) {
PaymentProcessor processor = new PaymentProcessor();
PaymentMethod card = new CreditCard();
PaymentMethod paypal = new PayPal();
processor.processPayment(card, 100);
processor.processPayment(paypal, 200);
}
}
```
Этот подход делает систему легко расширяемой: если нужно добавить новый способ оплаты, можно просто реализовать новый класс, не изменяя существующий код.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[ООП|ООП]]
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,24 @@
---
aliases:
- leaky abstractions
tags:
- maturity/🌱
date: 2024-09-27
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
linked:
---
Детали реализации или логика одного [[Архитектурный слой|архитектурного слоя]] становятся видимыми или начинают оказывать влияние на другие слои системы. Это нарушает принцип [[Инкапсуляция|инкапсуляции]] и разделения ответственности.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-09-27]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -121,7 +121,7 @@ MySQL не решает из коробки проблемы кластериз
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[Mixed binlog format]]
- [[Row Based Replication (RBR)]] - [[Row Based Replication (RBR)]]
- [[Statement Based Replication (SBR)]] - [[Statement Based Replication (SBR)]]
- [[Mixed binlog format]]
<!-- SerializedQuery END --> <!-- SerializedQuery END -->

View File

@ -37,7 +37,7 @@ linked:
### Дочерние заметки ### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) --> <!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
- [[B-tree]]
- [[Бинарное дерево поиска]] - [[Бинарное дерево поиска]]
- [[Сбалансированное дерево]] - [[Сбалансированное дерево]]
- [[B-tree]]
<!-- SerializedQuery END --> <!-- SerializedQuery END -->

View File

@ -57,8 +57,12 @@ versionPatterns = [
] ]
``` ```
Запустить выполнение плагина: Также можно настроить передачу текста для сообщения в теге:
```
release.tagCommitMessage = project.findProperty('release.tagCommitMessage')
```
Запустить выполнение плагина:
```bash ```bash
gradle relase gradle relase
``` ```

View File

@ -2,7 +2,7 @@
aliases: aliases:
tags: tags:
- maturity/🌱 - maturity/🌱
- type/opinion - content/opinion
date: 2024-09-17 date: 2024-09-17
zero-link: zero-link:
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]" - "[[../../meta/zero/00 Java разработка|00 Java разработка]]"

View File

@ -2,7 +2,7 @@
aliases: aliases:
tags: tags:
- maturity/🌱 - maturity/🌱
- type/opinion - content/opinion
date: 2024-09-06 date: 2024-09-06
zero-link: zero-link:
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]" - "[[../../meta/zero/00 Java разработка|00 Java разработка]]"

View File

@ -2,7 +2,7 @@
aliases: aliases:
tags: tags:
- maturity/🌱 - maturity/🌱
- type/opinion - content/opinion
date: 2023-11-20 date: 2023-11-20
zero-link: zero-link:
- "[[00 Java разработка]]" - "[[00 Java разработка]]"

View File

@ -2,7 +2,7 @@
aliases: aliases:
tags: tags:
- maturity/🌱 - maturity/🌱
- type/opinion - content/opinion
date: 2023-11-20 date: 2023-11-20
zero-link: zero-link:
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]" - "[[../../meta/zero/00 Java разработка|00 Java разработка]]"

View File

@ -2,7 +2,7 @@
aliases: aliases:
tags: tags:
- maturity/🌱 - maturity/🌱
- type/opinion - content/opinion
date: 2024-09-06 date: 2024-09-06
zero-link: zero-link:
- "[[../../meta/zero/00 Java разработка|00 Java разработка]]" - "[[../../meta/zero/00 Java разработка|00 Java разработка]]"

View File

@ -0,0 +1,126 @@
---
aliases:
tags:
- maturity/🌱
- "#content/problem"
date: 2024-09-25
zero-link:
- "[[00 Разработка]]"
parents:
linked:
---
mozjpeg не устанавливается из обычных пакетных менеджеров для RHEL, его необходимо собирать вручную.
**Mozjpeg** использует **CMake** для сборки. Установим необходимые утилиты
```shell
sudo yum install cmake nasm make gcc git
```
Склонируем репозиторий:
```shell
git clone https://github.com/mozilla/mozjpeg.git
```
Соберем и установим **mozjpeg**
```shell
cd mozjpeg
mkdir build && cd build
cmake -G"Unix Makefiles" ..
make
sudo make install
```
> [!INFO] Путь установки
> По умолчанию **mozjpeg** устанавливается в каталог /opt/mozjpeg.
Добавим mozjpeg в PATH
```shell
export PATH=/opt/mozjpeg/bin:$PATH
```
Проверим, что все установилось успешно
```shell
cjpeg -version
```
## Проблема при установке
Во время запуска cmake я получил следующую проблему.
```shell
$ cmake -G"Unix Makefiles" ..
....
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11")
-- Found PNG: /usr/lib64/libpng.so (found suitable version "1.6.37", minimum required is "1.6")
-- PNG reading support enabled (PNG_SUPPORTED = 1)
-- Could NOT find ZLIB (missing: ZLIB_LIBRARY) (found version "1.2.11")
CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find PNG (missing: PNG_LIBRARY) (Required is at least version
"1.6")
Call Stack (most recent call first):
/usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake/Modules/FindPNG.cmake:159 (find_package_handle_standard_args)
CMakeLists.txt:778 (find_package)
-- Configuring incomplete, errors occurred!
```
Проблема связана с отсутствием необходимых библиотек разработки для **zlib** и **libpng**. Хотя из вывода **CMake** видно, что сначала он находит библиотеки **ZLIB** и **PNG**:
```shell
-- Found ZLIB: /usr/lib64/libz.so (found version "1.2.11")
-- Found PNG: /usr/lib64/libpng.so (found suitable version "1.6.37", minimum required is "1.6")
```
Я попытался установить нужные пакеты, но они уже были установлены.
```shell
sudo yum install zlib-devel libpng-devel
```
Я проверил наличие библиотек и заголовочных файлов. Они также были на месте.
```shell
ls /usr/lib64/libz.*
ls /usr/lib64/libpng.*
ls /usr/include/zlib.h
ls /usr/include/png.h
```
Я попробовал установить **pkg-config**, который помогает **CMake** находить пути к библиотекам и заголовочным файлам. И проверил, что **pkg-config** возвращает пути к библиотекам.
```shell
sudo yum install pkgconfig
pkg-config --libs zlib
pkg-config --libs libpng
```
Я пытался использовать cmake3 указывая пути до библиотек
```shell
cmake3 -G"Unix Makefiles" \
-DZLIB_LIBRARIES=/usr/lib64/libz.so \
-DZLIB_INCLUDE_DIR=/usr/include \
-DPNG_LIBRARY=/usr/lib64/libpng.so \
-DPNG_PNG_INCLUDE_DIR=/usr/include \
..
```
В итоге я решил просто отключить поддержку PNG для mozjpeg, раз с ней возникают проблемы, так как я планирую использовать mozjpeg только для сжатия jpeg файлов.
```shell
cmake -G"Unix Makefiles" -DPNG_SUPPORTED=OFF ..
```
И это в итоге помогло.
***
## Мета информация
**Область**:: [[../../../meta/zero/00 Разработка|00 Разработка]]
**Родитель**::
**Источник**::
**Создана**:: [[2024-09-25]]
**Автор**::
### Дополнительные материалы
-
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -77,8 +77,8 @@ enableToc: false
#maturity/🌳 - Самые качественные заметки. Работа над ними фактически завершилась. Больших изменений в ближайшее время не планируется. #maturity/🌳 - Самые качественные заметки. Работа над ними фактически завершилась. Больших изменений в ближайшее время не планируется.
**По типу контента:** **По типу контента:**
#type/opinion - Мое субъективное мнение по какой-то теме, по какому-то вопросу. #content/opinion - Мое субъективное мнение по какой-то теме, по какому-то вопросу.
#type/checklist - Различные полезные чек-листы. #content/checklist - Различные полезные чек-листы.
#type/archive - Архивные заметки. Их обновление не планируется, так как тема потеряла для меня интерес. #type/archive - Архивные заметки. Их обновление не планируется, так как тема потеряла для меня интерес.
## ☎️ Контакты ## ☎️ Контакты

View File

@ -8,4 +8,7 @@ zero-link:
- [Проверка свободного места на дисках](Проверка%20свободного%20места%20на%20дисках.md) - [Проверка свободного места на дисках](Проверка%20свободного%20места%20на%20дисках.md)
CentOS: CentOS:
- [Настройка прокси на CentOS 7 и 8](../../dev/linux/centos/Настройка%20прокси%20на%20CentOS%207%20и%208.md) - [Настройка прокси на CentOS 7 и 8](../../dev/linux/centos/Настройка%20прокси%20на%20CentOS%207%20и%208.md)
## Полезное
- [Packages for Linux and Unix](https://pkgs.org/). Можно найти любой доступный пакет

View File

@ -5,6 +5,8 @@ parents:
- "[[00 Разработка]]" - "[[00 Разработка]]"
title: Архитектура ПО title: Архитектура ПО
--- ---
Не бывает плохой или хорошей архитектуры, бывает подходящая под ситуацию и не подходящая. Каждая архитектура имеет свои плюсы и минусы. И главная задача хорошего архитектора определить какая архитектура подходит в данной конкретной ситуации.
- [[../../../../_inbox/Architecture Significant Requirement|Architecture Significant Requirement]] - [[../../../../_inbox/Architecture Significant Requirement|Architecture Significant Requirement]]

View File

@ -4,3 +4,8 @@ tags:
zero-link: zero-link:
- "[[00 Разработка]]" - "[[00 Разработка]]"
--- ---
- [[../../dev/architecture/Архитектурный слой|Архитектурный слой]]
Архитектурные ошибки и проблемы:
- [[../../dev/architecture/Протекание абстракций|Протекание абстракций]]
- [[../../../../_inbox/Необоснованное использование ORM в слое бизнес-логики|Необоснованное использование ORM в слое бизнес-логики]]

View File

@ -19,4 +19,4 @@ aliases:
- [[../../dev/snippet/Реализация SHA-256 на Java|Реализация SHA-256 на Java]] - [[../../dev/snippet/Реализация SHA-256 на Java|Реализация SHA-256 на Java]]
- [[../../../../_inbox/Реализация GZIP в Java|Реализация GZIP в Java]] - [[../../../../_inbox/Реализация GZIP в Java|Реализация GZIP в Java]]
- [[../../dev/snippet/Реализация Base64 на Java|Реализация Base64 на Java]] - [[../../dev/snippet/Реализация Base64 на Java|Реализация Base64 на Java]]
- [[../../../../_inbox/Преобразование Json из коллекции в Java объект при помощи Jackson|Преобразование Json из коллекции в Java объект при помощи Jackson]] - [[../../dev/snippet/Преобразование Json из коллекции в Java объект при помощи Jackson|Преобразование Json из коллекции в Java объект при помощи Jackson]]

View File

@ -15,7 +15,7 @@ linked:
- Говорите на языке фактов, а не оценочных суждений. - Говорите на языке фактов, а не оценочных суждений.
- Приходите с решением. - Приходите с решением.
- Проясняйте ожидания. - Проясняйте ожидания.
- Давайте и запрашиваете [обратную связь](Обратная%20связь.md). - Давайте и запрашиваете [обратную связь](../../../knowledge/education/Обратная%20связь.md).
- Создавайте и сохраняйте прозрачность. Понятно что происходит вокруг. Понятны процессы. - Создавайте и сохраняйте прозрачность. Понятно что происходит вокруг. Понятны процессы.
- Своевременность. Хвалите вовремя, ругайте вовремя. - Своевременность. Хвалите вовремя, ругайте вовремя.
- Решайте проблему, а не ситуацию и симптомы возникшие от проблемы. - Решайте проблему, а не ситуацию и симптомы возникшие от проблемы.

View File

@ -8,8 +8,8 @@ date:
zero-link: zero-link:
- "[[../meta/zero/00 Психология|00 Психология]]" - "[[../meta/zero/00 Психология|00 Психология]]"
parents: parents:
- "[[Мозг]]" - "[[../health/human/Мозг]]"
linked: linked:
--- ---
Когнетивные искажения возникают из-за того, что наш мозг ленив и пытается упростить себе жизнь. Когнетивные искажения возникают из-за того, что наш мозг ленив и пытается упростить себе жизнь.
@ -21,7 +21,7 @@ linked:
*** ***
## Мета информация ## Мета информация
**Область**:: [[../meta/zero/00 Психология|00 Психология]] **Область**:: [[../meta/zero/00 Психология|00 Психология]]
**Родитель**:: [[../../../knowledge/human/строение/органы/Мозг|Мозг]] **Родитель**:: [[../health/human/Мозг|Мозг]]
**Источник**:: **Источник**::
**Автор**:: **Автор**::
**Создана**:: [[2024-08-13]] **Создана**:: [[2024-08-13]]