React 架构
React Native在App领域大行其道,尤其是鸿蒙拥抱RN之后。
React 本身是一套UI库,属于表现层。其架构通常结合以下模式:
组件化: 通过组合可复用的组件构建UI页面。
视图组件
容器组件
单向数据流: 父组件向子组件传递数据。
状态管理: 可以搭配 Redux/ Context API 或MobX
Context API 轻量级全局状态管理。
Redux 复杂状态管理。
MobX 响应式状态管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24// 创建 Context
const ThemeContext = createContext('light');
// 容器组件
const App = () => {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={theme}>
<Toolbar onChangeTheme={setTheme} />
</ThemeContext.Provider>
);
};
// 展示组件
const Toolbar = ({ onChangeTheme }) => {
const theme = useContext(ThemeContext);
return (
<button
onClick={() => onChangeTheme(theme === 'light' ? 'dark' : 'light')}
>
Toggle Theme ({theme})
</button>
);
};
优缺点
- 优点:
- 组件化开发,复用性强。
- 生态丰富(支持多种状态管理库)。
- 缺点:
- 复杂项目需额外架构设计(如引入 Redux)。
BLoC (flutter)
核心思想
BLoC 通过事件Event → 处理 → 状态 的流管理业务逻辑,实现UI与逻辑的解耦。
核心组件
Event: 用户触发的动作(Event)
Bloc 处理事件并生成新的状态。
State 当前UI状态
Stream 数据流管道
优缺点
- 优点:
- 逻辑与 UI 完全解耦,适合复杂交互。
- 通过 Stream 实现高效状态管理。
- 缺点:
- 需要熟悉 Stream 和异步编程。
- 小型项目可能显得冗余。
1 | // Event |
Redux
核心思想
基于Flux 架构,通过单向数据流管理应用状态。
Store 全局唯一状态容器。
Action 描述状态变化示意图。
Reducer 纯函数,根据Action 生成新状态。
数据流向
View 触发Action
Reducer 处理Action 生成新State
View 根据新State更新
代码示例
1 | // Action Types |
优缺点
- 优点:
- 状态可预测,便于调试(如时间旅行调试)。
- 适合复杂状态管理(如多组件共享数据)。
- 缺点:
- 样板代码多,小型项目不适用。
- 学习曲线较陡峭。
Clean Architecture
核心思想
强调分层解耦、依赖规则。 确保业务逻辑独立于框架、数据库或者UI。
核心原则:
依赖倒置原则
分层结构: 从内到外:Entities Use Cases Interface Adapters Frameworks & Drivers
| 层级 | 职责 | 示例组件 |
|---|---|---|
| Entities | 核心业务规则和数据结构(如 User、Order) |
数据模型、业务校验逻辑 |
| Use Cases | 具体业务场景(如 LoginUseCase、FetchProductsUseCase) |
协调数据流,调用 Repositories |
| Interface Adapters | 将核心逻辑适配到外部系统(如数据库、UI、网络) | Presenters、Controllers、Gateways |
| Frameworks & Drivers | 具体技术实现(如数据库操作、HTTP 请求) | SQLite、REST API 客户端、UIKit |
1 | // Entity |
优缺点
- 优点:
- 业务逻辑与技术实现完全解耦,适合长期维护。
- 支持多平台复用核心层(如 Web、iOS、Android 共享 Use Cases)。
- 缺点:
- 分层复杂,小型项目可能过度设计。
- 需要严格遵循依赖规则。
MVC
MVVM
VIPER
软件设计原则
代码设计原则:
依赖倒置原则
单一职责原则
接口隔离原则
迪米特法则
开闭原则
里氏替换原则
以下是 6个核心软件设计原则 的详细解析,涵盖其核心思想、实践示例和关键注意事项,帮助你构建 高内聚、低耦合、易维护 的代码。
1. 单一职责原则(SRP, Single Responsibility Principle)
核心思想:
一个类/模块/函数只应承担 一个职责(即只有一个引起它修改的原因)。示例:
1
2
3
4
5
6
7
8
9
10// 错误示例:User 类同时处理数据存储和校验
class User {
void saveToDatabase() { /* 数据库操作 */ }
boolean validateEmail() { /* 校验逻辑 */ }
}
// 正确示例:拆分职责
class User { /* 仅保存数据 */ }
class UserValidator { boolean validateEmail(User user) { ... } }
class UserRepository { void save(User user) { ... } }优点:
代码更易维护、测试和复用。注意:
职责划分的粒度需结合实际场景,避免过度拆分。
2. 开闭原则(OCP, Open-Closed Principle)
核心思想:
软件实体(类、模块等)应对 扩展开放,对 修改关闭。实现方式:
通过 抽象接口 或 继承 扩展行为,而非修改原有代码。示例:
1
2
3
4
5
6
7
8
9
10# 抽象支付接口
class PaymentProcessor:
def process(self, amount): pass
# 扩展新支付方式无需修改原有代码
class StripeProcessor(PaymentProcessor):
def process(self, amount): print("Stripe支付处理")
class PayPalProcessor(PaymentProcessor):
def process(self, amount): print("PayPal支付处理")优点:
提升系统稳定性和可扩展性。注意:
过度抽象可能导致设计复杂度上升。
3. 里氏替换原则(LSP, Liskov Substitution Principle)
核心思想:
子类必须能完全替代父类,且不破坏程序的正确性。反例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Rectangle {
int width, height;
void setWidth(int w) { width = w; }
void setHeight(int h) { height = h; }
}
class Square extends Rectangle {
// 违反LSP:重写方法导致行为不一致
void setWidth(int w) { width = height = w; }
void setHeight(int h) { width = height = h; }
}
// 使用父类的方法会得到错误结果
void test(Rectangle r) {
r.setWidth(5);
r.setHeight(4);
assert(r.area() == 20); // 若传入Square,结果为25,断言失败
}修正方案:
避免继承关系违背业务逻辑,优先使用组合。优点:
确保继承体系的健壮性。
4. 接口隔离原则(ISP, Interface Segregation Principle)**
核心思想:
客户端不应被迫依赖它不需要的接口方法。示例:
1
2
3
4
5
6
7
8
9
10
11
12// 错误示例:臃肿接口
interface Animal {
eat(): void;
fly(): void; // 鸟类需要,鱼类不需要
}
// 正确示例:拆分接口
interface Eatable { eat(): void; }
interface Flyable { fly(): void; }
class Bird implements Eatable, Flyable { ... }
class Fish implements Eatable { ... }优点:
减少接口污染,降低依赖冗余。注意:
接口粒度需平衡,避免碎片化。
5. 依赖倒置原则(DIP, Dependency Inversion Principle)
核心思想:
- 高层模块不依赖低层模块,二者都应依赖抽象。
- 抽象不应依赖细节,细节应依赖抽象。
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 抽象消息发送接口
interface MessageSender {
void send(String message);
}
// 高层模块依赖抽象
class NotificationService {
private MessageSender sender;
NotificationService(MessageSender sender) { this.sender = sender; }
void sendAlert(String msg) { sender.send(msg); }
}
// 低层实现细节
class EmailSender implements MessageSender { ... }
class SMSSender implements MessageSender { ... }优点:
提升代码灵活性和可测试性。实现工具:
依赖注入(DI)框架(如 Spring、Dagger)。
6. 迪米特法则(LoD, Law of Demeter / 最少知识原则)
核心思想:
一个对象应尽可能少地与其他对象交互,仅与直接朋友通信(如方法参数、成员变量)。反例:
1
2# 链式调用违反LoD
user.get_address().get_city().get_street()修正方案:
封装中间逻辑,暴露简化接口。1
2
3
4# 在User类中封装
class User:
def get_street(self):
return self.address.city.street优点:
降低模块间耦合,提高可维护性。
总结:原则的核心价值
| 原则 | 核心目标 | 适用场景 |
|---|---|---|
| SRP | 职责单一化 | 模块设计、类方法拆分 |
| OCP | 扩展性优先 | 插件化系统、多态业务逻辑 |
| LSP | 继承安全 | 类层次结构设计 |
| ISP | 接口精简 | 避免接口污染 |
| DIP | 依赖抽象 | 模块解耦、依赖管理 |
| LoD | 减少交互 | 复杂对象网络 |
灵活运用原则,而非教条遵循——根据项目规模和团队经验平衡设计复杂度! 🛠️
设计模式
创建型
单例模式
工厂模式
抽象工厂模式
建造者
原型
结构型
适配器模式
桥接模式
组合模式
装饰器模式
外观模式
享元模式
行为型
责任链模式
命令模式
观察者模式
解释器模式
迭代器模式
中介者模式
备忘录模式
状态模式
策略模式
模版方法
访问者模式