refactor: заменены вкладки на скрывающиеся блоки для лучшей совместимости

- Заменены HTML вкладки на нативные скрывающиеся блоки (details/summary)
- Добавлены эмодзи иконки для каждого языка программирования
- Удален CSS и JavaScript код для упрощения
- Улучшена совместимость с любыми Markdown редакторами
- Все примеры кода теперь в collapsible секциях
This commit is contained in:
Alexander Abakumov committed 2025-09-10 00:21:35 +03:00
1 parent c7b37b9297
commit f9afd30663
1 file changed
+76 -161
@@ -120,15 +120,8 @@
#### Примеры реализации
<div class="tabs">
<div class="tab-buttons">
<button class="tab-btn active" onclick="showTab('monolith-java', this)">Java</button>
<button class="tab-btn" onclick="showTab('monolith-rust', this)">Rust</button>
<button class="tab-btn" onclick="showTab('monolith-js', this)">JavaScript</button>
<button class="tab-btn" onclick="showTab('monolith-python', this)">Python</button>
</div>
<div id="monolith-java" class="tab-content active">
<details>
<summary><strong>🔧 Java (Spring Boot)</strong></summary>
```java
// Монолитная архитектура
@@ -192,9 +185,11 @@ public class OrderController {
}
}
```
</div>
<div id="monolith-rust" class="tab-content">
</details>
<details>
<summary><strong>🦀 Rust (Actix Web)</strong></summary>
```rust
// Монолитная архитектура
@@ -247,9 +242,11 @@ async fn create_order(
Ok(web::Json(order))
}
```
</div>
<div id="monolith-js" class="tab-content">
</details>
<details>
<summary><strong>🟨 JavaScript (Node.js)</strong></summary>
```javascript
// Монолитная архитектура
@@ -277,9 +274,11 @@ fastify.post('/api/orders', async (request, reply) => {
return order;
});
```
</div>
<div id="monolith-python" class="tab-content">
</details>
<details>
<summary><strong>🐍 Python (FastAPI)</strong></summary>
```python
# Монолитная архитектура
@@ -310,8 +309,8 @@ async def create_order(request: CreateOrderRequest):
order = await order_service.create_order(request)
return order
```
</div>
</div>
</details>
### 2. SQL vs NoSQL
@@ -353,15 +352,8 @@ async def create_order(request: CreateOrderRequest):
#### Примеры реализации
<div class="tabs">
<div class="tab-buttons">
<button class="tab-btn active" onclick="showTab('sql-java', this)">Java</button>
<button class="tab-btn" onclick="showTab('sql-rust', this)">Rust</button>
<button class="tab-btn" onclick="showTab('sql-js', this)">JavaScript</button>
<button class="tab-btn" onclick="showTab('sql-python', this)">Python</button>
</div>
<div id="sql-java" class="tab-content active">
<details>
<summary><strong>🔧 Java (Spring Boot + JPA)</strong></summary>
```java
// SQL подход (PostgreSQL)
@@ -420,9 +412,11 @@ public class MongoUser {
}
}
```
</div>
<div id="sql-rust" class="tab-content">
</details>
<details>
<summary><strong>🦀 Rust (SQLx)</strong></summary>
```rust
// SQL подход (PostgreSQL)
@@ -503,9 +497,11 @@ async fn create_user_with_order(
Ok(user)
}
```
</div>
<div id="sql-js" class="tab-content">
</details>
<details>
<summary><strong>🟨 JavaScript (Node.js)</strong></summary>
```javascript
// SQL подход (PostgreSQL)
@@ -593,9 +589,11 @@ async function createUserWithOrderMongo(request) {
return await user.save();
}
```
</div>
<div id="sql-python" class="tab-content">
</details>
<details>
<summary><strong>🐍 Python (SQLAlchemy)</strong></summary>
```python
# SQL подход (PostgreSQL)
@@ -671,8 +669,8 @@ def create_user_with_order_mongo(request):
user['_id'] = result.inserted_id
return user
```
</div>
</div>
</details>
### 3. REST vs GraphQL
@@ -713,15 +711,8 @@ def create_user_with_order_mongo(request):
#### Примеры реализации
<div class="tabs">
<div class="tab-buttons">
<button class="tab-btn active" onclick="showTab('rest-java', this)">Java</button>
<button class="tab-btn" onclick="showTab('rest-rust', this)">Rust</button>
<button class="tab-btn" onclick="showTab('rest-js', this)">JavaScript</button>
<button class="tab-btn" onclick="showTab('rest-python', this)">Python</button>
</div>
<div id="rest-java" class="tab-content active">
<details>
<summary><strong>🔧 Java (Spring Boot)</strong></summary>
```java
// REST API
@@ -749,9 +740,11 @@ public class UserResolver implements GraphQLResolver<User> {
}
}
```
</div>
<div id="rest-rust" class="tab-content">
</details>
<details>
<summary><strong>🦀 Rust (Actix Web)</strong></summary>
```rust
// REST API
@@ -787,9 +780,11 @@ const resolvers = {
}
};
```
</div>
<div id="rest-js" class="tab-content">
</details>
<details>
<summary><strong>🟨 JavaScript (Node.js)</strong></summary>
```javascript
// REST API
@@ -807,9 +802,11 @@ const resolvers = {
}
};
```
</div>
<div id="rest-python" class="tab-content">
</details>
<details>
<summary><strong>🐍 Python (FastAPI + Strawberry)</strong></summary>
```python
# REST API
@@ -825,8 +822,8 @@ class User:
async def orders(self) -> List[Order]:
return await order_service.find_by_user_id(self.id)
```
</div>
</div>
</details>
### 4. Стратегии кэширования
@@ -1027,15 +1024,8 @@ class User:
#### Примеры реализации
<div class="tabs">
<div class="tab-buttons">
<button class="tab-btn active" onclick="showTab('cache-java', this)">Java</button>
<button class="tab-btn" onclick="showTab('cache-rust', this)">Rust</button>
<button class="tab-btn" onclick="showTab('cache-js', this)">JavaScript</button>
<button class="tab-btn" onclick="showTab('cache-python', this)">Python</button>
</div>
<div id="cache-java" class="tab-content active">
<details>
<summary><strong>🔧 Java (Spring Boot + Redis)</strong></summary>
```java
// Cache-Aside Pattern
@@ -1091,9 +1081,11 @@ public class UserServiceWriteThrough {
}
}
```
</div>
<div id="cache-rust" class="tab-content">
</details>
<details>
<summary><strong>🦀 Rust (Redis + Tokio)</strong></summary>
```rust
// Cache-Aside Pattern
@@ -1151,9 +1143,11 @@ impl UserService {
}
}
```
</div>
<div id="cache-js" class="tab-content">
</details>
<details>
<summary><strong>🟨 JavaScript (Node.js + Redis)</strong></summary>
```javascript
// Cache-Aside Pattern
@@ -1227,9 +1221,11 @@ class UserServiceWriteBehind {
}
}
```
</div>
<div id="cache-python" class="tab-content">
</details>
<details>
<summary><strong>🐍 Python (FastAPI + Redis)</strong></summary>
```python
# Cache-Aside Pattern
@@ -1302,8 +1298,8 @@ class UserService:
except Exception as e:
print(f"Async save error: {e}")
```
</div>
</div>
</details>
## Рекомендации по выбору
@@ -1404,86 +1400,5 @@ class UserService:
> **💡 Совет**: Документируйте архитектурные решения в Architecture Decision Records (ADR) для будущих поколений разработчиков.
<style>
.tabs {
margin: 20px 0;
border: 1px solid #e1e4e8;
border-radius: 6px;
overflow: hidden;
}
.tab-buttons {
display: flex;
background-color: #f6f8fa;
border-bottom: 1px solid #e1e4e8;
}
.tab-btn {
flex: 1;
padding: 12px 16px;
border: none;
background: transparent;
cursor: pointer;
font-size: 14px;
font-weight: 500;
color: #586069;
transition: all 0.2s ease;
}
.tab-btn:hover {
background-color: #e1e4e8;
color: #24292e;
}
.tab-btn.active {
background-color: #fff;
color: #0366d6;
border-bottom: 2px solid #0366d6;
}
.tab-content {
display: none;
padding: 0;
background: #fff;
}
.tab-content.active {
display: block;
}
.tab-content pre {
margin: 0;
border-radius: 0;
border: none;
background: #f6f8fa;
padding: 16px;
overflow-x: auto;
}
.tab-content code {
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
font-size: 13px;
line-height: 1.45;
}
</style>
<script>
function showTab(tabId, button) {
// Найти родительский контейнер вкладок
const tabsContainer = button.closest('.tabs');
// Скрыть все вкладки в этом контейнере
const contents = tabsContainer.querySelectorAll('.tab-content');
contents.forEach(content => content.classList.remove('active'));
// Убрать активный класс со всех кнопок в этом контейнере
const buttons = tabsContainer.querySelectorAll('.tab-btn');
buttons.forEach(btn => btn.classList.remove('active'));
// Показать выбранную вкладку
document.getElementById(tabId).classList.add('active');
button.classList.add('active');
}
</script>