Angular中的工厂模式?

时间:2016-02-24 12:36:55

标签: javascript angularjs

有人提到我应该使用下面的真实工厂模式,所以我不必经常提供typeName。如何在JavaScript和Angular中实现这一点。如果它是C#,我就不会有问题,但Java参考/值类型和Angular会让我的大脑受伤。

(function () {

    'use strict';

    angular
        .module('blocks.object-cache');

    objectCache.$inject = ['CacheFactory', '$auth'];

    function objectCache(CacheFactory, $auth) {

        var _options = {
            maxAge : (60 * 60 * 1000),
            deleteOnExpire : 'passive',
            storageMode : 'localStorage'
        };

        var service = {
            setOptions          : setOptions,
            getCache            : getCache,

            clear               : clear,

            getAll              : getAll,
            getItem             : getItem,
            getItems            : getItems,

            putItem             : putItem,
            putItems            : putItems,

            getItemsByKey       : getItemsByKey,
            getItemByKeyFirst   : getItemByKeyFirst,
            getItemByKeySingle  : getItemByKeySingle,


            removeItemsByKey    : removeItemsByKey,
            removeItemByKey     : removeItemByKey,

            putItemsByKey       : putItemsByKey,
            putItemByKey        : putItemByKey
        };

        return service;
        ////////////////////////////////////////////////////////////////////////////////

        function setOptions (options) {
            options = options || {};
            options.maxAge = options.maxAge = _options.maxAge;
            options.deleteOnExpire = options.deleteOnExpire = _options.deleteOnExpire;
            options.storageMode = options.storageMode = _options.storageMode;
            _options = options;
        }
        function getCache(typeName) {
            var cacheName = [getUserId(), normalizeTypeName(typeName || 'objects')].join('_');
            var cache = CacheFactory(cacheName);
            if (cache) { return cache; }
            cache = CacheFactory(cacheName, _options);
            return cache;
        }

        function clear (typeName) {
            var cache = getCache(typeName);
            cache.removeAll();
            return (!cache.keys() || (cache.keys().length < 1));
        }

        function getAll (typeName) {
            var cache = getCache(typeName);
            var result = [];
            (cache.keys() || []).forEach(function(key){
                result.push(cache(key));
            });
            return result;
        }
        function getItem(typeName, id) {
            if (typeof id == 'undefined' || !id.trim) { return null; }
            var cache = getCache(typeName);
            return cache.get(id);
        }
        function getItems(typeName, ids) {
            var cache = getCache(typeName),
                result = [],
                _ids   = [];
            (ids || []).forEach(function(id){
                if (_ids.indexOf(id) < 0) {
                    _ids.push(id);
                    var item = cache.get(id);
                    if (item) { result.push(item); }
                }
            });
            return result;
        }

        function putItem(typeName, item, id, refresh) {
            if (typeof item == 'undefined') { return false; }
            if (typeof id == 'undefined' || !id.trim) { return false; }
            var cache = getCache(typeName);
            var existing = cache.get(id);
            if (existing && !refresh) { return true; }
            if (existing) { cache.remove(id); }
            cache.put(item, id);
            return (!!cache.get(id));
        }
        function putItems(typeName, items, idField, refresh) {
            var cache = getCache(typeName);
            (items || []).forEach(function(item){
                var id = item[idField];
                if (typeof id != 'undefined') {
                    var existing = cache.get(id);
                    if (existing && !!refresh) { cache.remove(id); }
                    if (!existing || !!refresh) { cache.put(item, id); }
                    if (!cache.get(id)) { return false; }
                }
            });
            return true;
        }

        function getItemsByKey(typeName, key, value, isCaseSensitive) {
            var result = [];
            (getAll(typeName) || []).forEach(function(item){
                var itemValue = item[key];
                if (typeof itemValue != 'undefined') {
                    if ((typeof value == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || value.toLowerCase() == itemValue.toLowerCase())) {
                        result.push(item);
                    } else if (((typeof value) == (typeof itemValue)) && (value == itemValue)) {
                        result.push(item);
                    } else {
                        // Other scenarios?
                    }
                }
            });
            return result;
        }
        function getItemByKeyFirst(typeName, key, value, isCaseSensitive) {
            var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
            return (items.length > 0) ? items[0] : null;
        }
        function getItemByKeySingle(typeName, key, value, isCaseSensitive) {
            var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
            return (items.length === 0) ? items[0] : null;
        }

        function removeItemsByKey (typeName, keyField, values, isCaseSensitive) {
            var cache = getCache(typeName),
                keysToRemove = [];
            (cache.keys() || []).forEach(function(key){
                var item        = cache.get[key],
                    itemValue   = item[keyField];
                if (typeof itemValue != 'undefined') {
                    for (var v = 0; v < (values || []).length; v += 1) {
                        if ((typeof values[v] == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || values[v].toLowerCase() == itemValue.toLowerCase())) {
                            keysToRemove.push(key);
                            break;
                        } else if (((typeof values[v]) == (typeof itemValue)) && (values[v] == itemValue)) {
                            keysToRemove.push(key);
                            break;
                        } else {
                            // Other scenarios?
                        }
                    }
                }
            });
            var success = true;
            keysToRemove.forEach(function(key){
                cache.remove(key);
                if (cache.get(key)) { success = false; }
            });
            return success;
        }
        function removeItemByKey (typeName, keyField, value, isCaseSensitive) {
            return removeItemsByKey(typeName, keyField, [value], isCaseSensitive);
        }

        function putItemsByKey(typeName, items, keyField, refresh, isCaseSensitive) {
            if (!!refresh) {
                var values  = _.map((items || []), keyField);
                if (!removeItemsByKey(typeName, keyField, values, isCaseSensitive)) { return false; }
            }
            var cache = getCache(typeName);
            (items || []).forEach(function(item){
                var id = item[keyField];
                if (typeof value != 'undefined') { cache.put(item, id); }
                if (!cache.get(id)) { return false; }
            });
            return true;
        }
        function putItemByKey(typeName, item, keyField, refresh, isCaseSensitive) {
            return putItemsByKey(typeName, [item], keyField, refresh, isCaseSensitive);
        }

        function getUserId () {
            return $auth.isAuthenticated() ? ($auth.getPayload().sub || 'unknown') : 'public';
        }
        function normalizeTypeName (typeName) {
            return typeName.split('.').join('-');
        }
    }

})();

1 个答案:

答案 0 :(得分:0)

我不是一个角色大师,但你不能只是移动这些功能来实现类似工厂的模式吗?我没有测试过这个,但大约有两分钟的复制粘贴...

编辑:删除了嵌套的迭代函数。

(function () {

    'use strict';

    angular
        .module('blocks.object-cache')
        .service('ObjectCache', ObjectCache);

    ObjectCache.$inject = ['CacheFactory', '$auth'];

    function ObjectCache(CacheFactory, $auth) {

        var _options = {
            maxAge : (60 * 60 * 1000),
            deleteOnExpire : 'passive',
            storageMode : 'localStorage'
        };

        var factory = {
            getCache : getCache
        };

        return factory;
        ////////////////////////////

        function getCache(typeName, options) {

            options = options || {};
            options.maxAge = options.maxAge = _options.maxAge;
            options.deleteOnExpire = options.deleteOnExpire = _options.deleteOnExpire;
            options.storageMode = options.storageMode = _options.storageMode;

            typeName    = normalizeTypeName(typeName || 'objects');
            var userId  = getUserId() || 'public';
            var name    = userId + '_' + typeName;

            var service = {
                type    : typeName,
                user    : userId,
                name    : name,
                options : options,
                cache   : CacheFactory(name) || CacheFactory.createCache(name, options),
                clear   : function () {
                    this.cache.removeAll();
                },
                getAll  : function () {
                    var result = [];
                    var keys = this.cache.keys() || [];
                    for (var i = 0; i < keys.length; i += 1) {
                        result.push(this.cache(keys[i]));
                    }
                    return result;
                },
                getItems : function (ids) {
                    var result = [],
                        _ids   = [];
                    for (var i = 0; i < (ids || []).length; i += 1) {
                        var id = ids[i];
                        if (_ids.indexOf(id) < 0) {
                            _ids.push(id);
                            var item = this.cache.get(id);
                            if (item) { result.push(item); }
                        }
                    }
                    return result;
                },
                getItem  : function (id) {
                    var items = this.getItems([id]);
                    return (items.length > 0) ? items[0] : null;
                },
                putItem  : function (item, id, refresh) {
                    var existing = this.cache.get(id);
                    if (existing && !refresh) { return true; }
                    if (existing) { this.cache.remove(id); }
                    this.cache.put(item, id);
                    return (!!this.cache.get(id));
                },
                putItems : function (items, idField, refresh) {
                    var success = true;
                    for (var i = 0; i < (items || []).length; i += 1) {
                        var item = items[i];
                        var id   = item[idField];
                        if (typeof id != 'undefined') {
                            if (this.putItem(item, id, refresh)) { success = false; }
                        }
                    }
                    return success;
                },
                getItemsByKey : function (key, value, isCaseSensitive) {
                    var result = [];
                    (this.getAll() || []).forEach(function(item){
                        var itemValue = item[key];
                        if (typeof itemValue != 'undefined') {
                            if ((typeof value == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || value.toLowerCase() == itemValue.toLowerCase())) {
                                result.push(item);
                            } else if (((typeof value) == (typeof itemValue)) && (value == itemValue)) {
                                result.push(item);
                            } else {
                                // Other scenarios?
                            }
                        }
                    });
                    return result;
                },
                getItemByKeyFirst : function (key, value, isCaseSensitive) {
                    var items = this.getItemsByKey(key, value, isCaseSensitive) || [];
                    return (items.length > 0) ? items[0] : null;
                },
                getItemByKeySingle : function (key, value, isCaseSensitive) {
                    var items = this.getItemsByKey(key, value, isCaseSensitive) || [];
                    return (items.length === 0) ? items[0] : null;
                },
                removeItemsByKey : function (keyField, values, isCaseSensitive) {
                    var keysToRemove = [],
                        keys = this.cache.keys() || [];
                    for (var k = 0; k < keys.length; k += 1) {
                        var key     = keys[k];
                        var item    = this.cache.get(key);
                        var itemVal = item[keyField];
                        if (typeof itemVal != 'undefined') {
                            for (var v = 0; v < (values || []).length; v += 1) {
                                if ((typeof values[v] == 'string') && (typeof itemVal == 'string') && (!isCaseSensitive || values[v].toLowerCase() == itemVal.toLowerCase())) {
                                    keysToRemove.push(key);
                                    break;
                                } else if (((typeof values[v]) == (typeof itemVal)) && (values[v] == itemVal)) {
                                    keysToRemove.push(key);
                                    break;
                                } else {
                                    // Other scenarios?
                                }
                            }
                        }
                    }
                    var success = true;
                    for (var r = 0; r < keysToRemove.length; r += 1) {
                        this.cache.remove(keysToRemove[r]);
                        if (this.cache.get(keysToRemove[r])) { success = false; }
                    }
                    return success;
                },
                removeItemByKey : function (keyField, value, isCaseSensitive) {
                    return this.removeItemsByKey(keyField, [value], isCaseSensitive);
                },
                putItemsByKey : function(items, keyField, refresh, isCaseSensitive) {
                    if (!!refresh) {
                        var values  = _.map((items || []), keyField);
                        if (!this.removeItemsByKey(keyField, values, isCaseSensitive)) { return false; }
                    }
                    for (var i = 0; i < (items || []).length; i += 1) {
                        var id = items[i][keyField];
                        if (typeof id != 'undefined') {
                            this.cache.put(items[i], id);
                            if (!this.cache.get(id)) { return false; }
                        }
                    }
                    return true;
                },
                putItemByKey : function (item, keyField, refresh, isCaseSensitive) {
                    return this.putItemsByKey([item], keyField, refresh, isCaseSensitive);
                }
            };

            return service;
        }


        function getUserId () {
            return $auth.isAuthenticated() ? ($auth.getPayload().sub || 'unknown') : null;
        }
        function normalizeTypeName (typeName) {
            return typeName.split('.').join('-');
        }
    }

})();