Шаблон фабрика (Factory)

Dec 1, 2019

Шаблон фабрика (Factory)

Шаблон фабрика (Factory) использует класс Factory, чтобы возвратить экземпляр определенного класса на основе переданных классу данных.

Например, ниже мы определили 3 класс Baby, Child, Adult. Каждый из которых наследует абстрактный класс Person.

Далее мы создаем экземпляр фабрики: factory = new PersonFactory();.

Далее при помощи фабричного метода factory.getPerson мы создаем экземпляр класса (из трех возможных Baby, Child, Adult) в зависимости от даты, которая передается фабричному методу.

enum PersonCategory {
    Baby,
    Child,
    Adult
}

interface IPerson {
    Category: PersonCategory;
    canSign(): boolean;
    showDetails(): void;
}

abstract class Person implements IPerson {
    Category: PersonCategory;
    private DateOfBirth: Date;

    constructor(dateOfBirth: Date) {
        this.DateOfBirth = dateOfBirth;
        this.Category = PersonCategory.Undefined;
    }

    abstract canSign(): boolean

    showDetails(): void {
        console.log(`Персона : `);
        console.log(`День рождения : `
            + `${this.DateOfBirth.toDateString()}`);
        console.log(`Категория      : `
            + `${PersonCategory[this.Category]}`);
        console.log(`Может ставить подпись      : `
            + `${this.canSign()}`);
    }
}


class Baby extends Person {
    constructor(dateOfBirth: Date) {
        super(dateOfBirth);
        this.Category = PersonCategory.Baby;
    }
    canSign(): boolean { return false; }
}

class Child extends Person {
    constructor(dateOfBirth: Date) {
        super(dateOfBirth);
        this.Category = PersonCategory.Child;
    }
    canSign(): boolean { return false; }
}

class Adult extends Person {
    constructor(dateOfBirth: Date) {
        super(dateOfBirth);
        this.Category = PersonCategory.Adult;
    }
    canSign(): boolean { return true; }
}

class PersonFactory {
    getPerson(dateOfBirth: Date): IPerson {
        let dateNow = new Date(),
            currentMonth = dateNow.getMonth() + 1,
            currentDate = dateNow.getDate();

        let dateTwoYearsAgo = new Date(
            dateNow.getFullYear() - 2,
            currentMonth, currentDate);

        let date18YearsAgo = new Date(
            dateNow.getFullYear() - 18,
            currentMonth, currentDate);

        if (dateOfBirth >= dateTwoYearsAgo) {
            return new Baby(dateOfBirth);
        }
        if (dateOfBirth >= date18YearsAgo) {
            return new Child(dateOfBirth);
        }
        return new Adult(dateOfBirth);
    }
}

let factory = new PersonFactory();
let p1 = factory.getPerson(new Date(2019, 0, 22));
p1.showDetails();
let p2 = factory.getPerson(new Date(2010, 0, 22));
p2.showDetails();
let p3 = factory.getPerson(new Date(1979, 0, 22));
p3.showDetails();
Добавить комментарий