前言
设计模式七大原则
- 开闭原则:对扩展开放,对修改关闭
- 里氏代换原则:任何基类出现的地方,子类一定可以出现。(抽象化)子类可以扩展父类的功能,但不能修改父类对父类的功能
- 依赖倒转原则:针对接口编程,依赖于抽象而不依赖于具体实现。
- 接口隔离原则:使用多个隔离的接口,比使用一个接口好。(降低耦合度)
- 迪米特法则:一个实体应尽量少的和其他实体之间发生相互作用
- 合成复用原则:尽量使用合成聚合,而不是继承
- 单一职责原则: 一个类应该只做一件事
类图之间关系
- 依赖关系:虚线箭头,箭头从使用类指向被依赖的类(通常类中方法通过变量/参数/或静态方法来调用另一个类中的方法)
- 关联关系:实线箭头,双向可无箭头(通常一个类的对象作为另一个类的成员变量)
- 聚合关系:has-a (整体与部分) 空心菱形实线,菱形指向整体,部分可以脱离整体如学校和老师
- 组合关系:实心菱形实线,菱形指向整体,包含关系,部分不可以脱离整体
- 泛化关系:is-a 继承 实线空心三角形,三角形指向父类
- 实现关系:接口与实现类,虚线空心三角形,指向接口类
总体分类
分为三类:创建型 / 结构型 /行为型
- 创建型:关注如何创建对象,特点是将对象的创建和使用分开
- 结构性:如何将类或对象按某种布局组成更大的结构
- 行为型:关注对象之间的行为
工厂模式
定义
定义一个创建产品的工厂接口。将产品的创建推迟到具体工厂类中。
分类
简单工厂:只需一个工厂类即可完成。并且创建实例的方法一般是静态的,故又称为静态工厂方法模式。
工厂方法模式:简单工厂的进一步抽象,需要多个工厂类分别创建不同的产品。
抽象工厂模式:生产多种产品。
优缺点
简单工厂
优点:
- 客户端无需知道产品类别,只需知道参数
- 客户端免除创建产品的指责
缺点:
- 工厂类职责过重。
- 扩展困难,并且需要增加新的工厂类,违背了开闭原则
工厂方法
优点:
- 用户无需知道具体工厂和具体产品创建。
- 灵活性强,新产品,只需多添加工厂。
- 满足迪米特/依赖倒置/里氏替换原则。
缺点:
- 类个数增多,增加复杂度
- 只能产生一种产品
抽象工厂
优点:
- 类内部可以对产品族进行管理
- 保证客户端使用使用一个产品的产品族
- 增加产品族时 不需要修改源代码
缺点:
- 产品族中增加新产品时,需要修改工厂类。
ts代码实现
简单工厂
interface Shape{ //产品类
draw(): void;
}
class Circle implements Shape{
draw(){
console.log('circle')
}
}
class Rectangle implements Shape{
draw(){
console.log('circle')
}
}
class Factory { //工厂类
public static getShape(type: string): Shape{ //静态类型
if(type === 'circle'){
return new Circle()
}
else if(type === 'rectangle'){
return new Rectangle()
}
return null
}
}
class Test{
public getProduction(){
let factory = new Factory();
let circle:Shape = factory.getShape('circle')
circle.draw()
let rectangle: Shape = factory.getShape('circle')
rectangle.draw()
}
}
let t = new Test()
t.getProduction();
工厂方法
//相比于抽象工厂,只具有一个产品族
interface Animal{ //产品类
fly():void;
}
class Bird implements Animal{
fly(){
console.log('bird fly')
}
}
class Bee implements Animal{
fly(){
console.log("bee fly")
}
}
abstract class AbstractFactoryMethod{ //抽象工厂类
abstract getProduction(): Animal
}
class BirdFactory extends AbstractFactoryMethod{
getProduction(){
return new Bird()
}
}
class BeeFactory extends AbstractFactoryMethod{
getProduction(){
return new Bee()
}
}
抽象工厂
interface Shape{ //产品类1
draw():void
}
class Square implements Shape{
draw(){
console.log("Square")
}
}
class Diamond implements Shape{
draw(){
console.log("Diamond")
}
}
interface Color { //产品类2
fill():void;
}
class Red implements Color{
fill(){
console.log('red')
}
}
class Yellow implements Color{
fill(){
console.log('yellow')
}
}
abstract class AbstractFactory { //抽象工厂列
abstract getColor(): Color;
abstract getShape(): Shape;
}
class Factory1 extends AbstractFactory{
getShape(){
return new Square()
}
getColor(){
return new Red()
}
}
class Factory2 extends AbstractFactory{
getColor(){
return new Yellow()
}
getShape(){
return new Diamond()
}
}
class FactoryProducer{
public getFactory(factory: string): AbstractFactory{
if(factory === '1'){
return new Factory1()
}
else if(factory === '2'){
return new Factory2()
}
return null
}
}
let factory = new FactoryProducer();
let fa1 = factory.getFactory('1');
let shape = fa1.getShape();
shape.draw()
let color1 = fa1.getColor();
color1.fill()