工程化
git和svn 的区别
问题 | Git | SVN |
---|---|---|
模型类型 | 分布式(Distributed) | 集中式(Centralized) |
核心差异 | - 每个开发者本地有完整仓库副本 - 数据分散存储,支持离线操作 | - 所有代码存储在中央服务器 - 必须联网才能提交代码 |
分支实现 | - 轻量级分支(创建 / 切换耗时毫秒级) - 基于指针(commit 哈希),不复制文件 | - 重量级分支(基于文件系统复制) - 耗存储、操作慢(尤其大项目) |
合并能力 | - 支持三方合并(自动识别共同祖先) - 冲突解决灵活(可视化工具如 VS Code) | - 依赖路径匹配,跨分支合并易出错 - 复杂场景需手动处理冲突 |
git常用命令
js
git init // 新建 git 代码库
git add // 添加指定文件到暂存区
git rm // 删除工作区文件,并且将这次删除放入暂存区
git commit -m [message] // 提交暂存区到仓库区
git branch // 列出所有分支
git checkout -b [branch] // 新建一个分支,并切换到该分支
git status // 显示有变更文件的状态
git pull 和 git fetch 的区别
- git fetch 只是将远程仓库的变化下载下来,并没有和本地分支合并。
- git pull 会将远程仓库的变化下载下来,并和当前分支合并。
git rebase 和 git merge 的区别
git merge 和 git rebase 都是用于分支合并,关键在 commit 记录的处理上不同:
- git merge 会新建一个新的 commit 对象,然后两个分支以前的 commit 记录都指向这个新 commit 记录。这种方法会保留之前每个分支的 commit 历史。
- git rebase ,当前所在分支为源分支,rebase xx中的xx为目标分支,会先找到两个分支的第一个共同的 commit 祖先记录,然后将提取源分支这之后的所有 commit 记录,然后将这个 commit 记录添加到目标分支的最新提交后面。经过这个合并后,两个分支合并后的 commit 记录就变为了线性的记录了。
设计模式
创造模式
单例模式
确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
工厂模式
简单工厂
通过一个工厂生产所有产品
js
// 产品接口
class Product {
operation() { return "Base product"; }
}
// 具体产品
class ConcreteProductA extends Product {
operation() { return "Product A"; }
}
class ConcreteProductB extends Product {
operation() { return "Product B"; }
}
// 简单工厂
class Factory {
createProduct(type) {
if (type === "A") return new ConcreteProductA();
if (type === "B") return new ConcreteProductB();
throw new Error("Invalid product type");
}
}
// 使用工厂
const factory = new Factory();
const productA = factory.createProduct("A");
console.log(productA.operation()); // 输出: "Product A"
工厂方法
工厂提供一个接口,子类实现接口
js
// 工厂基类
abstract class Creator {
abstract factoryMethod(): Product; // 抽象产品,具体产品由子类实现
someOperation() {
const product = this.factoryMethod();
return `Operation with ${product.operation()}`;
}
}
// 具体工厂
class ConcreteCreatorA extends Creator {
factoryMethod() { return new ConcreteProductA(); }
}
class ConcreteCreatorB extends Creator {
factoryMethod() { return new ConcreteProductB(); }
}
// 使用工厂
const creatorA = new ConcreteCreatorA();
console.log(creatorA.someOperation()); // 输出: "Operation with Product A"
结构型模式
适配器模式
当两个接口不兼容(如旧接口与新系统不匹配),通过一个 “适配器” 中间层,将一个接口转换为另一个接口,使原本无法一起工作的组件可以协同
js
// 目标接口(新系统需要的接口)
interface ImagePrinter {
printImage(image: string): void;
}
// 被适配者(旧接口,不兼容新系统)
class OldPrinter {
printText(text: string): void {
console.log(`OldPrinter 打印文本:${text}`);
}
}
// 适配器(组合被适配者,转换接口)
class PrinterAdapter implements ImagePrinter {
private oldPrinter: OldPrinter; // 持有被适配者实例
constructor(oldPrinter: OldPrinter) {
this.oldPrinter = oldPrinter;
}
// 将 printImage 转换为旧接口的 printText
printImage(image: string): void {
// 模拟图片转文本逻辑(实际可能更复杂)
const text = "图片内容"+image;
this.oldPrinter.printText(text);
}
}
// 使用示例
const oldPrinter = new OldPrinter();
const adapter = new PrinterAdapter(oldPrinter);
adapter.printImage("风景.jpg"); // 输出:OldPrinter 打印文本:图片内容:风景.jpg
装饰器模式
js中还是试验性功能,ts中可以使用
主要用在类和方法上,相较于继承是静态的,装饰器可以动态添加,会在类或者方法定义完后再运行装饰器
行为型设计模式
观察者模式
观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新
被观察者内部维护了一个观察者数组,当自身发生变化时,会触发观察者的更新函数
vue3中的响应式就是利用了观察者模式,定义时收集依赖,修改状态时,会触发依赖的更新。
发布订阅模式
发布者和订阅者需要通过发布订阅中心进行关联,发布者的发布动作和订阅者的订阅动作相互独立,无需关注对方,消息派发由发布订阅中心负责。
类似vue中的事件总线机制,通过on将事件和回调挂载到总线上,通过emit触发事件来执行所有的相关回调。