在开始聊IOC工厂前,先说一个我在洗澡时想到的故事。

话说某一部最新的007的电影要开拍了。导演放话给制片说,007要开拍了。现在需要邦×××一名。要求如下,

天使的面孔,魔鬼的身材。

经纪人A和制片比较熟。就和制片说。我这里有个妹子,天使的面孔魔鬼的身材。

制片说。好了就让你包装的妹子上吧。

合同签了。经纪人A就发愁了。还没妹子给我包装啊。

这时他的好朋友经纪人B就给他说了。别怕。我这里有个妹子,天使的面孔,魔鬼的身材。

经纪人A一听就高兴了。好兄弟,就你了。

合同签了,经纪人B就发愁了。唉。。我哪里有妹子啊。先骗个合同混口饭吃。

这时,B看见马路对面出现一个妹子。哇 天使的面孔 魔鬼的身材。就上去搭讪说。

妹子,我这里有个007的电影女一号,你有兴趣么?妹子一听,立马答应下来给B进行包装。

这下大家都开心了。电影如期开拍。

电影拍完了。制片给经纪人A说,这里是100万的支票,这段时间辛苦了。

A给B说,这里是80万的支票,这段时间辛苦了。

B给妹子说,这里是60万的支票,这段时间辛苦了。。

故事到这里就结束了。下面是故事当中的扮演者名单

导演:对象调用者,

制片:IOC工厂,

邦×××要求:接口,

经纪人A&B:接口包装类

妹子:接口继承类


从这个故事可以看出,对于导演来说,他并不关心也不知道制片给他找了一个什么人。只要求符合他的接口就可以了。

而对于妹子来说,因为他的出演是经过2个经纪人进行了包装的,所以只能拿到60万的支票。


好了故事分享完了。我们就开始分享一下核心代码吧。

var Factory = function () {
    //单例模式
    if (arguments.callee.instance) {
        return arguments.callee.instance;
    }
    arguments.callee.instance = this;
    var dic = {};
    var getInstByRegister = function (reg) {
        if (!reg) throw "require type<" + key + "> not registed";
        switch (reg.InstType) {
            case Enum.InstType.Normal:
                return new reg.type();
                break;
            case Enum.InstType.Singleton:
                return reg.type;
                break;
            case Enum.InstType.Decorate:
                return new reg.type(getInstByRegister(reg.NextReg));
        }
    }
    var getReg = function (interface, key) {
        var interfaceCode = interface.GetHashCode();
        var iDic = getIDic(interface);
        if (key && iDic[key]) {
        } else {
            key = "base";
        }
        var reg = iDic[key];
        return reg;
    }
    var getIDic = function (interface) {
//获取 类型的唯一值 以进行注册
        var interfaceCode = interface.GetHashCode();
        if (!dic[interfaceCode]) {
            dic[interfaceCode] = {};
        }
        var iDic = dic[interfaceCode];
        return iDic;
    }
//获取实例
//param: 接口类 关键字
    this.getInst = function (interface, key) {
        if (this.Register != null && this.Register.Check) {
            this.Register.Check();
        }
        var reg = getReg(interface, key);
        return getInstByRegister(reg);
    }
    this.Register = null;
//注册 装饰类
//param:接口类 装饰类 装饰关键字
    this.RegistDecorate = function (interface, type, key) {
        if (!key) { key = "base" };
        try {
            var reg = getReg(interface, key);
            var iDic = getIDic(interface);
            var newReg = { InstType: Enum.InstType.Decorate, type: type, NextReg: reg };
            iDic[key] = newReg;
        } catch (ex) {
            throw "toDecorate inst not regist";
        }
    }
//注册类
//param:接口类 注册类 是否单例 关键字
    this.Regist = function (interface, type, isSingleton, key) {
        var instType = Enum.InstType.Normal;
        if (isSingleton) {
            instType = Enum.InstType.Singleton;
        }
        var iDic = getIDic(interface);
        if (!key) key = "base";
        if (isSingleton) {
            type = new type();
        }
        iDic[key] = { InstType: instType, type: type };
    }
}
Factory.getInst = function (interface, key) {
    var obj = new Factory();
    return obj.getInst(interface, key);
}