设计模式学习篇-工厂模式

83 阅读2分钟

1. 概念

简单的概念理解,创建对象或者方法的时候通过统一的方法来实现

2. 分类

工厂模式可以分为三类:简单工厂,工厂方法和抽象工厂。一般前面两种比较常见,抽象工厂用的比较少

2.1 简单工厂

它使用一个单独的工厂类来创建不同的对象,根据传入的参数决定创建哪种类型的对象。具体实现方式也有两种,参考单例模式的实现方式,饿汉式和懒汉式

2.1.1 举例

比如在游戏中需要根据不同的渠道读取不同的config文件,就 可以通过一个ConfigFactory类通过传参数来获得当前的渠道配置,代码如下

interface IConfig {
    channel: string;
    url: string;
}

class ITXConfig implements IConfig {
    channel: string;
    url: string;
    appid: string;
}

class ITapConfig implements IConfig {
    channel: string;
    url: string;
    key: string
}

class ConfigFactory {
    public static getConfig(channel: string): IConfig {
        switch (channel) {
            case 'tx':
                return new ITXConfig();
            case 'tap':
                return new ITapConfig();
            default:
                return {
                    channel: channel,
                    url: 'https://test.com'
                }
        }
    }
}

//使用
//ConfigFactory.getConfig('tap').channel

2.2 工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。

class ITXConfig implements IConfig {
    channel: string;
    url: string;
    appid: string;
}

class ITapConfig implements IConfig {
    channel: string;
    url: string;
    key: string
}

interface IConfigManager {
    getConfig(): IConfig
}

class TXConfigManager implements IConfigManager {
    public getConfig(): IConfig {
        return new ITXConfig();
    }
}

class TapConfigManager implements IConfigManager {
    public getConfig(): IConfig {
        return new ITapConfig();
    }
}

class ConfigManage {
    private _manger: IConfigManager = null;

    public getFactory(channel: string): IConfigManager {
        switch (channel) {
            case 'tx':
                this._manger = new TXConfigManager();
                break;
            case 'tap':
                this._manger = new TapConfigManager()
                break;
        }
        return this._manger;
    }

    public getConfig(): IConfig {
        return this._manger.getConfig();
    }
}

这个是简单的工厂方法的实现,对于ConfigMange.getFactory这边的switch语句,也可以对此进行工厂的简单工厂实现,具体代码如下

class ConfigManage {
    private static _map: Map<string, IConfigManager> = new Map<string, IConfigManager>();
    private _manger: IConfigManager = null;
    constructor(channel: string) {
        ConfigManage._map.set('tx', new TXConfigManager());
        ConfigManage._map.set('tap', new TapConfigManager());

        this._manger = ConfigManage._map.get(channel);
    }

    public getFactory(channel: string): IConfigManager {
        return new ConfigManage(channel);
    }

    public getConfig(): IConfig {
        return this._manger.getConfig();
    }
}

2.3 抽象工厂模式

简单理解就是,抽象工厂包含了多个工厂,每个工厂都有自己对应的工厂模式 举例:因为暂时没想到游戏中哪里需要使用抽象方法所以直接抄了例子

interface Shape {
    draw();
}

class Rect implements Shape {
    draw() {
        console.log('draw rect');
    }
}

class Circle implements Shape {
    draw() {
        console.log('draw circle');
    }
}



interface Color {
    fill();
}

class Red implements Color {
    fill() {
        console.log('fill red');
    }
}

class Green implements Color {
    fill() {
        console.log('fill green');
    }
}

interface AbstractFactory {
    getColor(color: string): Color;
    getShape(shape: string): Shape;
}

class ShapeFactory implements AbstractFactory {
    getColor(color: string): Color {
        return null;
    }
    getShape(shape: string): Shape {
        switch (shape) {
            case 'rect':
                return new Rect();
            case 'circle':
                return new Circle();
            default:
                return null;
        }
    }
}

class ColorFactory implements AbstractFactory {
    getColor(color: string): Color {
        switch (color) {
            case 'red':
                return new Red();
            case 'green':
                return new Green();
            default:
                return null;
        }
    }
    getShape(shape: string): Shape {
        return null;
    }
}

// 使用
let shapeFactory = new ShapeFactory();
let colorFactory = new ColorFactory();
shapeFactory.getShape('rect').draw();
colorFactory.getColor('red').fill();