1. 前言
- 前几天面试也问到了这个问题
- 首先
低耦合
其次拖拽
来分析- 当时主要是
react
问的 所以用react代码
来说明
2. 是什么 what
- 低耦合性是指在
软件设计
中,模块或组件之间的相互依赖
程度较低
的特性。- 当组件之间的耦合性低时,它们可以
独立
存在、修改和测试,而不会对其他组件产生太大的影响。- 低耦合性有助于
提高
代码的可维护性
、可扩展性
和可重用
性。
3. 实现方式 -模块化设计:
- 将系统
拆分
成多个独立
的模块,每个模块只关注自身
的功能,并提供清晰的接口
供其他模块使用。模块之间的通信
通过接口
进行,而不是直接依赖于具体实现。
- 大概代码思路
// 模块A import { doSomething } from './moduleB'; function ModuleA() { // 使用模块B提供的功能 doSomething(); // 组件A的其他逻辑 // ... } // 模块B export function doSomething() { // 执行某些操作 }
4. 解耦合的通信方式:
- 采用
解耦合
的通信方式,如事件驱动
或发布
-订阅模式,以减少模块之间的直接依赖。这样,模块之间的通信
可以通过事件或消息进行,而不需要直接引用其他模块。
- 大概代码
// 事件驱动方式 // 组件A function ComponentA() { function handleClick() { // 触发事件 EventBus.emit('customEvent', data); } // 组件A的其他逻辑 // ... } // 组件B function ComponentB() { useEffect(() => { // 订阅事件 EventBus.on('customEvent', handleEvent); return () => { // 取消订阅 EventBus.off('customEvent', handleEvent); }; }, []); function handleEvent(data) { // 处理事件 // ... } // 组件B的其他逻辑 // ... }
5. 依赖注入:
- 通过
依赖注入
的方式,将组件所需的依赖
作为参数
传递给组件,而不是在组件内部直接创建或引用依赖对象。这样可以使组件更加灵活,易于替换和测试。
- 代码
// 父组件 function ParentComponent() { const dependency = { // 依赖对象或函数 }; return ( <ChildComponent dependency={dependency} /> ); } // 子组件 function ChildComponent({ dependency }) { // 使用依赖对象或函数 dependency.doSomething(); // 子组件的其他逻辑 // ... }
6. 接口设计:
- 良好的接口设计可以将组件之间的耦合降到最低。接口应该简洁明确,只提供必要的功能,并尽量减少对其他模块的依赖。
- 代码
// 接口定义 const API = { getData: () => { // 获取数据的实现 }, sendData: (data) => { // 发送数据的实现 }, }; // 组件 function Component() { // 使用接口定义的功能 API.getData(); // 组件的其他逻辑 // ... }
7. 具体的 低耦合拖拽项目
- 上面大概了解了 低耦合项目的方式 模块化设计,解耦合的通信方式,依赖注入,接口设计
- 下面看下具体的 低耦合 拖拽实现 思路
- 定义可拖拽的元素:创建一个组件或者元素,设置其可拖拽属性,例如 draggable="true"。
监听
拖拽事件:在拖拽元素上添加
拖拽事件的监听器,包括 dragstart、drag 和 dragend 事件。可以通过使用事件处理函数
来处理这些事件。- 实现拖拽的逻辑:在
dragstart
事件中,可以获取拖拽
元素的数据
,并将其存储到数据传输对象
(DataTransfer)中。可以使用自定义的数据属性或者其他方式存储数据。- 接收拖拽的目标区域:在接收拖拽的
目标区域
上添加相应的事件监听器
,包括 dragenter、dragover、dragleave 和 drop 事件。同样可以通过事件处理函数
来处理这些事件。- 实现拖拽目标的逻辑:在 dragover 事件中,可以阻止
默认
的拖放行为,并指示浏览器允许放置操作
。在 drop 事件中,可以获取拖拽元素的数据,并进行相应的处理。
import React from 'react'; const DraggableItem = ({ data, onDragStart }) => { const handleDragStart = (event) => { event.dataTransfer.setData('text/plain', JSON.stringify(data)); onDragStart(data); }; return ( <div draggable="true" onDragStart={handleDragStart}> {/* 拖拽元素的内容 */} </div> ); }; const DroppableTarget = ({ onDrop }) => { const handleDragOver = (event) => { event.preventDefault(); }; const handleDrop = (event) => { event.preventDefault(); const data = JSON.parse(event.dataTransfer.getData('text/plain')); onDrop(data); }; return ( <div onDragOver={handleDragOver} onDrop={handleDrop}> {/* 接收拖拽的目标区域的内容 */} </div> ); }; const App = () => { const handleDragStart = (data) => { // 拖拽开始时的处理逻辑 }; const handleDrop = (data) => { // 拖拽结束时的处理逻辑 }; return ( <div> <DraggableItem data={/* 拖拽元素的数据 */} onDragStart={handleDragStart} /> <DroppableTarget onDrop={handleDrop} /> </div> ); }; export default App;
- DraggableItem 组件代表
可拖拽
的元素,DroppableTarget
组件代表接收拖拽的目标区域
。- 通过
传递
相应的数据
和回调函数
,可以在 App 组件中实现特定的拖拽行为