SOLID

Single Responsibility Принцип єдиності відповідальності

Open Closed Принцип відкритості / закритості

Liskov Substitution Принцип заміщення Лісков

Interface Segregation Принцип поділу інтерфейсу

Dependency Inversion Принцип інверсії залежності

S

Single Responsibility 

S    bad example

class Order {
    calcTotalSum(): number {}
    getItems(): iOrder[] {}
    getItem(id: number): iOrder {}
    addItem(id: number): void {}
    deleteItem(id: number): void {}

    showOrder(): void {}
    printOrder(): void {}

    load(): iOrder[] {}
    save(): boolean {}
    update(): boolean {}
    delete(): boolean {}
}

S    good example

class Order {
    calcTotalSum(): number {}
    getItems(): iOrder[] {}
    getItem(id: number): iOrder {}
    addItem(id: number): void {}
    deleteItem(id: number): void {}
}

class OrderRepository {
    load(): iOrder[] {}
    save(): boolean {}
    update(): boolean {}
    delete(): boolean {}
}

class OrderViewer {
    showOrder(): void {}
    printOrder(): void {}
}

S    project example

@Component
class SomeCmp extends Vue {
    openingVideo: boolean = false

    @loading('openingVideo', false)
    onOpenVideo(video: iGalleryVideo) {
        if (this.openingVideo) return
    
        return apiProfile
            .video(video.id)
            .then(showVideo)
    }
}

S    project example

@Component
class SomeCmp extends Vue {
    openingVideo: boolean = false

    @loading({
        key: 'openingVideo',
        hasBlock: true,
        resultVal: false,
    })
    onOpenVideo(video: iGalleryVideo) {    
        return apiProfile
            .video(video.id)
            .then(showVideo)
    }
}

S    project example

@Component
class SomeCmp extends Vue {
    openingVideo: boolean = false

    @block('openingVideo', true)
    @loading('openingVideo')
    onOpenVideo(video: iGalleryVideo) {
        return apiProfile
            .video(video.id)
            .then(showVideo)
    }
}

S    project example

@Component
class SomeCmp extends Vue {
    openingVideo: boolean = false
    dataFetching: boolean = false

    @block('openingVideo', true)
    @loading('openingVideo', false)
    @loading('openingVideo', true)
    onOpenVideo(video: iGalleryVideo) {
        return apiProfile
            .video(video.id)
            .then(showVideo)
    }
}

O

Кожен метод класу повинен бути відкритий для розширення але закритий для модифікацій

O

{
    device: 'laptop',

    os: 'mac',

    version: 12.12
}

 

001010 -> pc win 10

000110 -> laptop ubuntu 14

L

Якщо в програмі об'єкти замінити їх наслідниками то властивості програми не зміняться

class Reactangle {
    private _width: number
    private _height: number

    get width() {
        return this._width
    }

    get height() {
        return this._height
    }

    public setWidth(width: number) {
        this._width = width
    }

    public setHeight(height: number) {
        this._height = height
    }
}
class Square extends Reactangle {
    setWidth(width: number) {
        super.setWidth(width)
        super.setHeight(width)
    }

    setHeight(height: number) {
        super.setWidth(height)
        super.setHeight(height)
    }
}

function calcRectangleSquare(
    rec: Reactangle,
    width: number,
    height: number,
) {
    rec.setWidth(width)
    rec.setHeight(height)

    return rec.height * rec.width
}
calcRectangleSquare(new Reactangle, 4, 5) // 20
calcRectangleSquare(new Square, 4, 5) // 25

I

Метод розділення інтерфейсів

I

interface iItem {
    applyDiscount(discount: number)
    applyPromocode(promocode: string)

    setColor(color: string)
    setSize(size: number)
    setMaterial(material: string)

    setCondition(condition: string)
    setPrice(price: number)
}
interface iApplyDiscountable {
    applyDiscount(discount: number)
    applyPromocode(promocode: string)
}

interface iClothes {
    setColor(color: string)
    setSize(size: number)
    setMaterial(material: string)
}

interface iItem {
    setCondition(condition: string)
    setPrice(price: number)
}
class Item implements iApplyDiscountable, iClothes {

}

D

Залежності в середині системи будуються на основі абстракцій

D

import Proccessor from 'proccessor'

export class Order {
    buyItem() {
        const proccessor = new Proccessor()

        return proccessor.checkout(this.order)
    }
}
import Proccessor from 'proccessor'

export class Order {
    buyItem(proccessor: iOrderProcessor) {
        return proccessor.checkout(this.order)
    }
}

D

import heroService from '../services/HeroService'

@Component
export class HeroListComponent implements OnInit {
  heroes: Hero[]
  selectedHero: Hero

  ngOnInit() {
    this.heroes = this.heroService.getHeroes()
  }

  selectHero(hero: Hero) {
    this.selectedHero = hero
  }
}

D

@Component
export class HeroListComponent implements OnInit {
  heroes: Hero[]
  selectedHero: Hero

  constructor(private heroService: HeroService) { }

  ngOnInit() {
    this.heroes = this.heroService.getHeroes()
  }

  selectHero(hero: Hero) {
    this.selectedHero = hero
  }
}

SOLID

By Kolya Koval

SOLID

  • 227