面向对象和 UML
面向对象的三大特征
1. 继承
继承主要是抽离公共代码,实现代码复用
2. 封装
封装实现高内聚,低耦合。
3. 多态
多态为了更好的扩展性
UML 类图
属性表示:
+ name: string
+ 代表 public
# 代表 protected
- 代表 private
name 表示属性
冒号后面是属性类型
方法表示:
+ eat():void
eat 表示方法名
()里面可以写参数名和类型
冒号后面是返回之值类型,如果没有返回值 可以不写或者用 void 表示
UML 类图关系
1. 实现
虚线空心箭头表示实现
interface IPerson {
name: string;
age: number;
eat(): void;
speak(): void;
}
class People implements IPerson {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
eat() {
console.log(`${this.name} eat something`);
}
speak() {
console.log(`My name is ${this.name}, age: ${this.age}`);
}
}
2. 泛化(继承)
实线空心箭头表示泛化也叫继承。
class Student extends People {
// 私有属性
private _sNo: string;
constructor(name: string, age: number, sNo: string) {
super(name, age);
this._sNo = sNo;
}
// 开放读取 但是不能修改
get SNo() {
return this._sNo;
}
}
3. 关联
一个类是一个类的属性就是关联。
// 身份证
class IdentityCard {
effectiveDate: Date;
birthday: Date;
constructor(effectiveDate, birthday) {
this.effectiveDate = effectiveDate;
this.birthday = birthday;
}
}
class People implements IPerson {
name: string;
age: number;
_identityCard: IdentityCard;
constructor(name: string, age: number, identityCard: IdentityCard) {
this.name = name;
this.age = age;
this._identityCard = identityCard;
}
eat() {
console.log(`${this.name} eat something`);
}
speak() {
console.log(`My name is ${this.name}, age: ${this.age}`);
}
get identityCard() {
return this._identityCard;
}
}
类图中关联的具体关系
-
聚合 - 整体包含部分, 部分可以脱离整体而单独存在。
-
组合 - 整题包含部分, 部分不可以脱离整体。
-
依赖 - 不是属性关系,而是类中的方法的一个参数或者返回值。
设计原则
SOLID五大设计原则
- S单一原则
一个类或模块应该只有一个引起它变化的原因。这意味着一个类或模块只负责一个特定的功能或任务,而不是多个不相关的功能。这样做可以提高类的内聚性,并使得类更容易理解、修改和测试。
- O开放封闭原则
软件实体(如类、模块或函数)应该对扩展开放,对修改封闭。这意味着在不修改现有代码的情况下,应该能够通过添加新的代码来扩展系统的功能。这可以使得系统更加稳定,减少修改现有代码可能带来的风险。
- L里氏替换原则
类型必须能够替换其基类型,且不会引发意外的行为。换句话说,任何可以接受基类型的地方都可以接受子类型,且不会引发意外的行为。这可以保持系统的一致性和可靠性,确保使用继承时不会破坏代码的正确性。
- I接口隔离原则
客户端不应该被迫依赖于其不使用的接口。这意味着应该将接口设计成小而专注的接口,而不是大而臃肿的接口。这可以降低耦合性,使得系统更加灵活和易于维护。
- D依赖反转原则
高层模块不应该依赖于低层模块,二者都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。这可以降低模块之间的耦合度,使得系统更易于扩展和修改。