精华内容
下载资源
问答
  • 本文发表于中文核心刊物《计算机工程与设计》2005年1期。     基于关系数据库数据仓库星形模式下维使用原则研究与探索  根峰

             本文发表于中文核心刊物《计算机工程与设计》2005年1期。

     

     

    基于关系数据库的数据仓库星形模式下维使用原则的研究与探索

                                                                                                          马根峰  

                                                                                         (广东电信公用电话管理中心  广州 510635)

    摘要    星形模式是基于关系数据库的数据仓库中的一个著名概念,由于星形连接模式的设计思想能够满足人们从不同观察角度(维)分析数据的需求,所以在基于关系数据库的数据仓库的设计中广泛地使用了星形模式。在使用数据仓库来回答综合性问题的场合,通常可以使用OLAP工具实现记录不多的较高粒度表的维度旋转来满足不同分析的需要;而在数据仓库中较高粒度表中记录非常多或者还要经常回答细节问题的场合,则还必须对数据仓库中记录非常多的较高粒度的表或者细节级表进行维度转换。但通常的OLAP工具难以处理几十万条记录数据表的维度旋转,针对这种应用场合,笔者提出了一种”有选择地使用维的星形模式”,在事实表中避开使用要旋转的维,用存贮过程编写程序高效地实现OLAP工具相应的功能,对星形模式下维的使用原则做出了一定的探索。

    关键词    数据仓库;星形模式;维度 ;OLAP

     

     

    the research of the restricted use of Dimensionality in Star Schema in Data Warehousing based on RDS

                                                                  MA Gen-feng     

             (Public Payphone Center, Guangdong Telecom Corporation, Guangzhou 510635)

    ABSTRACT:  Star Schema is a famous conception in Data Warehousing based on RDS. It’s widely used in Data Warehousing based on RDS for its convenience for people to analyze data from different angle. In the situation for people using Data Warehousing to answer the all-around question, OLAP tools is usually used to circumrotate the Dimensionality of high granularity tables with a few records for the requirement of analyse. If there is a great deal records in high granularity tables or In the situation for people using Data Warehousing to answer the detail question, it’s necessary to circumrotate the Dimensionality of those high granularity tables or the detail tables in Data Warehousing. While it’s very difficult for OLAP tools to circumrotate the dimensionality of tables with more than ten thousands records, I issue a new Star Schema with restricted using of dimensionality. In this Star Schema the fact tables without the dimensionality to be circumrotated is designed, then I develop a program using stored procedure to implement the corresponding function of OLAP tools in high efficiency. In this process definite research is done about the rule of using dimensionality in Star Schema in RDS.

    KEY WORDS: Data Warehousing; Star Schema; Dimensionality; OLAP

     

     

     

    1 引言

     

             星形模式是基于关系数据库的数据仓库中的一个著名概念,由于星形连接模式的设计思想能够满足人们从不同观察角度(维)分析数据的需求,加上数据仓库通常用来回答综合性的问题,并且通常的OLAP工具可以很轻松地实现记录不多的较高粒度表的维度旋转来满足不同分析的需要,所以在基于关系数据库的数据仓库的设计中广泛地使用了星形模式,如电信运营商中普遍进行的话务总体分析。在这种总体分析中,主要分析某一计费月各地区的总体话费及其在不同计费月期间的变化。

     

             而在数据仓库中较高粒度表中记录非常多或者还要经常回答细节问题的场合,则还必须对数据仓库中记录非常多的较高粒度的表或者细节级表进行维度转换。如在目前电信市场尤其是公话市场竞争激烈的今天,广东电信公用电话管理中心的经营分析人员迫切进行的公话终端(首先是一百多万部200专用话机)话费的动态分析。在这种话费的动态分析中,不仅要分析分析各地区、各市县、各支局、各用户类型以及它们不同组合情况下的200专用话机在某一计费月的总体话费及其在不同计费月的变化,而且还要从细节上分析带来这些变化的一百万多万部200专用话机在某一计费月的话费在不同计费月期间的变化。因为只有这样才能了解200专用话机总体话费及其变化的原因或找出其中的规律,为管理者决策提供依据。但通常的OLAP工具难以处理几十万条记录数据表的维度旋转,更不用说是对每个月都有一百多万条话费记录的200专用话机话费细节表在时间维度上的旋转了。笔者在”基于数据仓库和维度转换的广东电信公用电话200专用话机话务的动态分析系统”的研究与开发过程中,在数据仓库星形模式设计时有选择地使用维,在星形模式中各粒度200专用话机话费表中避开使用时间维,然后用存贮过程编写维度转换程序代替OLAP工具来旋转操作型环境下话费表中的时间维,在PC机上每一次只需要一个小时就完成了一个月一百多万条记录的操作型环境下话费表的维度转换并生成了数据仓库中各粒度表的数据,轻松地实现了一百多万部200专用话机话费的动态分析,对数据仓库星形模式下维的使用原则做出了一定的探索。

     

     

     

    2  只回答综合性问题场合下的星形模式及OLAP处理

     

      2.1 星形模式设计

             在只回答综合性问题的场合,也是绝大多数应用数据仓库的场合,由于OLAP只涉及数据仓库中记录不多的较高粒度的表,所以在这种场合,数据仓库中各粒度表都使用尽可能多维的星形模式。如下面电信运营商为了进行总体话费分析所采取的星形模式,在这种星形模式下,事实表中包含着用于分析的指标(话费)和联接众多维表的主键。

     

                        

      

     

     ......

     

         



        

     

    2.2  使用OLAP工具进行话费总体分析

             对于图2中的高度综合表,由于广东电信下属22个分公司,公用电话话机有20种类型,所以10年内表中的记录数为52800条记录,所以完全可以用OLAP工具对高度综合表进行维度转换,将时间维从事实表中去掉来完成几个月来各地区、各话机类型或者各地区的各种类型话机话费的总体变化,完成总体话费的分析。

     

     

     

    3 有选择地使用维的星形模式及话费动态分析的实现

     

             在图1至图3中,如果要进行各地区、各市县、各支局不同类型话机话费的动态分析,则还必须对图2中的轻度综合级表进行维度转换,而广东电信现有1400多个支局,那么一年内轻度综合级表中的记录就达到30多万条,在这种情况下用OLAP工具来分析几年间话费的变化就难以实现,更不用说对一年内就达1200多万条记录的200专用话机话费细节表进行200专用话机进行话费的动态分析了。笔者曾经使用OLAP工具BrioQuery在PC机上实现200万条记录的话费细节表在时间维度上的转换,运行135个小时也没有转换成功。在电信市场尤其是公话市场竞争日益激烈的今天,为了实现经营分析人员所迫切进行的200专用话机话费的动态分析,必须对上面的星形模式进行特殊的处理,笔者所采用的方法是在事实表中有选择地使用维,将事实表200专用话机话务中的时间维去掉,在事实表中增加各个时间维成员作为事实表的字段,使用存贮过程编写维度转换程序来代替OLAP的操作。

     

       3.1有选择地使用维的星形模式

         
                               


     …     


       


     

             对于关系模式的这种设计,大家可能会一方面质疑它的扩展性,即它能进行其它时期话费的动态分析吗?另一方面可能会质疑如果它可以扩展来进行其它时期话机话费的动态分析,那最多进行多少年话机话费的动态分析?在笔者开发的200专用话机话费的动态分析系统中,只要在选择性使用维的星形模式中各级话费表中增加几个月份的金额字段,在我编写的维度转换程序中增加几个变量及几条赋值语句,就可以统计分析许多年的话费数据;两者,MS SQL SERVER7.0最多支持1024列的表,这可以用来统计分析80多年的数据。

     

    3.2 话务表中时间维的旋转

             在笔者开发的200专用话机话费的动态分析系统中,笔者采用的方法是每个月对该月的话机话务表和图4中的细节表进行合并,这样做的优点一是每次只需要处理一个月一百多万条200专用话机话费记录,而不是像OLAP工具那样处理n个月的话费数据;二是经过查询优化,在PC机上每一个月200专用话机话费表的合并操作只需要一个小时的处理时间。具体合并过程如下图所示:

     
                                   

     

     

    4 结束语

     

             对于使用数据仓库来回答综合性问题的场合,星形连接模式可以满足决策者从不同的维来观察数据的需求,并且通常的OLAP工具可以实现记录不多的综合级表的维度旋转。笔者曾在PC机上使用某一OLAP工具来实现两个月200多万条话费记录的维度转换时,运行了xx小时也没有完成时间维的转换操作。而在数据仓库中较高粒度表中记录非常多或者还要经常回答细节问题的场合,则还必须对数据仓库中记录非常多的较高粒度的表或者细节级表进行维度转换。如分析电信运营商中几十万、几百万乃至于几千万部话机在时间维不同维成员的话费变化时,通常的OLAP工具却难以完成这样的操作。笔者在”广东电信公用电话200专用话机话务的动态分析系统”的研究与开发过程中,在数据仓库设计时有选择地使用维,在星形模式中各粒度200专用话机话费表中避开使用时间维,然后用存贮过程编写维度转换程序代替OLAP工具来旋转操作型环境下话费表中的时间维,在PC机上每一次只需要一个小时就完成了一个月一百多万条记录的话费表的维度转换并生成了数据仓库中各粒度表的数据,轻松地实现了一百多万部200专用话机话费的动态分析,对数据仓库星形模式下维的使用原则做出了一定的探索。

     

     

    参考文献:

    [1]  王珊 · 数据仓库技术与联机分析处理 · 北京:科学出版社,1998.6

    [2]  Michael Corey(美),Michael Abbey(美) · SQL SERVER 7 Data Warehousing · 北京:希望电子出版社,2000.1

    [3]  袁鹏飞 · SQL Server 7.0数据库系统管理与应用开发 · 北京:人民邮电出版社,1999.5

     

    展开全文
  • 整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法可以作为后来者的榜样。如果要知道怎样恰当定义和描述设计模式,我们应该可以从他们那儿获得启发”--steve...
  • 这里不会将UML各种元素都提到,我只想讲讲类图各个类之间的关系; 能看懂类图各个类之间线条、箭头代表什么意思后,也就足够应对 日常工作和交流; 同时,我们应该能将类图所表达含义和最终代码对应...

    看懂UML类图和时序图

    这里不会将UML的各种元素都提到,我只想讲讲类图中各个类之间的关系; 能看懂类图中各个类之间的线条、箭头代表什么意思后,也就足够应对 日常的工作和交流; 同时,我们应该能将类图所表达的含义和最终的代码对应起来; 有了这些知识,看后面章节的设计模式结构图就没有什么问题了;

    本章所有图形使用Enterprise Architect 9.2来画,所有示例详见根目录下的design_patterns.EAP

    从一个示例开始

    请看以下这个类图,类之间的关系是我们需要关注的:

    _images/uml_class_struct.jpg
    • 车的类图结构为<<abstract>>,表示车是一个抽象类;
    • 它有两个继承类:小汽车和自行车;它们之间的关系为实现关系,使用带空心箭头的虚线表示;
    • 小汽车为与SUV之间也是继承关系,它们之间的关系为泛化关系,使用带空心箭头的实线表示;
    • 小汽车与发动机之间是组合关系,使用带实心箭头的实线表示;
    • 学生与班级之间是聚合关系,使用带空心箭头的实线表示;
    • 学生与身份证之间为关联关系,使用一根实线表示;
    • 学生上学需要用到自行车,与自行车是一种依赖关系,使用带箭头的虚线表示;

    下面我们将介绍这六种关系;


    类之间的关系

    泛化关系(generalization)

    类的继承结构表现在UML中为:泛化(generalize)与实现(realize):

    继承关系为 is-a的关系;两个对象之间如果可以用 is-a 来表示,就是继承关系:(..是..)

    eg:自行车是车、猫是动物

    泛化关系用一条带空心箭头的直接表示;如下图表示(A继承自B);

    _images/uml_generalization.jpg

    eg:汽车在现实中有实现,可用汽车定义具体的对象;汽车与SUV之间为泛化关系;

    _images/uml_generalize.jpg

    注:最终代码中,泛化关系表现为继承非抽象类;

    实现关系(realize)

    实现关系用一条带空心箭头的虚线表示;

    eg:”车”为一个抽象概念,在现实中并无法直接用来定义对象;只有指明具体的子类(汽车还是自行车),才 可以用来定义对象(”车”这个类在C++中用抽象类表示,在JAVA中有接口这个概念,更容易理解)

    _images/uml_realize.jpg

    注:最终代码中,实现关系表现为继承抽象类;

    聚合关系(aggregation)

    聚合关系用一条带空心菱形箭头的直线表示,如下图表示A聚合到B上,或者说B由A组成;

    _images/uml_aggregation.jpg

    聚合关系用于表示实体对象之间的关系,表示整体由部分构成的语义;例如一个部门由多个员工组成;

    与组合关系不同的是,整体和部分不是强依赖的,即使整体不存在了,部分仍然存在;例如, 部门撤销了,人员不会消失,他们依然存在;

    组合关系(composition)

    组合关系用一条带实心菱形箭头直线表示,如下图表示A组成B,或者B由A组成;

    _images/uml_composition.jpg

    与聚合关系一样,组合关系同样表示整体由部分构成的语义;比如公司由多个部门组成;

    但组合关系是一种强依赖的特殊聚合关系,如果整体不存在了,则部分也不存在了;例如, 公司不存在了,部门也将不存在了;

    关联关系(association)

    关联关系是用一条直线表示的;它描述不同类的对象之间的结构关系;它是一种静态关系, 通常与运行状态无关,一般由常识等因素决定的;它一般用来定义对象之间静态的、天然的结构; 所以,关联关系是一种“强关联”的关系;

    比如,乘车人和车票之间就是一种关联关系;学生和学校就是一种关联关系;

    关联关系默认不强调方向,表示对象间相互知道;如果特别强调方向,如下图,表示A知道B,但 B不知道A;

    _images/uml_association.jpg

    注:在最终代码中,关联对象通常是以成员变量的形式实现的;

    依赖关系(dependency)

    依赖关系是用一套带箭头的虚线表示的;如下图表示A依赖于B;他描述一个对象在运行期间会用到另一个对象的关系;

    _images/uml_dependency.jpg

    与关联关系不同的是,它是一种临时性的关系,通常在运行期间产生,并且随着运行时的变化; 依赖关系也可能发生变化;

    显然,依赖也有方向,双向依赖是一种非常糟糕的结构,我们总是应该保持单向依赖,杜绝双向依赖的产生;

    注:在最终代码中,依赖关系体现为类构造方法及类方法的传入参数,箭头的指向为调用关系;依赖关系除了临时知道对方外,还是“使用”对方的方法和属性;

    时序图

    为了展示对象之间的交互细节,后续对设计模式解析的章节,都会用到时序图;

    时序图(Sequence Diagram)是显示对象之间交互的图,这些对象是按时间顺序排列的。时序图中显示的是参与交互的对象及其对象之间消息交互的顺序。

    时序图包括的建模元素主要有:对象(Actor)、生命线(Lifeline)、控制焦点(Focus of control)、消息(Message)等等。

    关于时序图,以下这篇文章将概念介绍的比较详细;更多实例应用,参见后续章节模式中的时序图;

    展开全文
  • 木马是一种基于C/S模式的远程控制技术,能在被监控对象毫无察觉的情况下渗透到对方系统并隐藏在合法程序中的计算机程序。一旦植入和触发成功,控制端与被控制端之间就能遵照TCP/IP协议进行数据通信,从而使得控制者...
  • 参考于 :  大话设计模式 ... 图来自大话设计模式,下面我代码,Clien是t依赖于Handler1和Handler2,不过可以使用配置文件或者直接给Filter集合初始化来解决这种依赖。   1.场景  在网...

    参考于 :

      大话设计模式

      马士兵设计模式视频

      代码参考于马士兵设计模式视频

      写在开头:职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系

      图来自大话设计模式,下面我的代码中,Clien是t依赖于Handler1和Handler2的,不过可以使用配置文件或者直接给Filter集合初始化来解决这种依赖。

      

     

    1.场景

      在网上评论一句话,往往会经过一系列的处理,有没有敏感词之类,现在我们来模拟一下。

      把<html>,o.o,和谐

      换成 [html],^v^,/*河蟹*/

    2.不使用职责链模式

      

    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 重点在于模式,故逻辑暂时不考虑
     * 
     * @author dingyu
     *
     */
    public class Client01 {
        public static void main(String[] args) {
            String s = "<html>,o.o,和谐";
            s = s.replace("<", "[").replace(">", "]").replace("和谐", "/*河蟹*/").replace("o.o", "^v^");
            System.out.println(s);
        }
    }

      缺点:过滤无法复用,无法记录过滤顺序。

    3.使用职责链模式

      

    package com.dingyu.ChainOfResponsibility;
    /**
     * 过滤器,doFilter处理msg字符串
     * @author dingyu
     *
     */
    public interface Filter {
        public String doFilter(String msg);
    }
    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 处理html符号
     * 测试用的,逻辑不是很严谨
     * @author dingyu
     *
     */
    public class HTMLFilter implements Filter {
    
        @Override
        public String doFilter(String msg) {
            return msg.replace("<", "[").replace(">", "]");
        }
    
    }
    package com.dingyu.ChainOfResponsibility;
    /**
     * 过滤敏感词汇
     * @author dingyu
     *
     */
    public class SensitiveWordFilter implements Filter {
    
        @Override
        public String doFilter(String msg) {
            return msg.replace("和谐", "/*河蟹*/");
        }
    
    }
    package com.dingyu.ChainOfResponsibility;
    /**
     * 处理符号
     * @author dingyu
     *
     */
    public class SymbolFilter implements Filter {
    
        @Override
        public String doFilter(String msg) {
            return msg.replace("o.o", "^v^");
        }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Client {
        private static List<Filter> filters = new ArrayList<Filter>();
        private static int index = 0;
    
        public static void main(String[] args) {
            String s = "<html>,o.o,和谐";
            filters.add(new HTMLFilter());
            filters.add(new SymbolFilter());
            filters.add(new SensitiveWordFilter());
            for (Filter filter : filters) {
                s = filter.doFilter(s);
            }
            System.out.println(s);
        }
    }

      虽然使用职责链模式,但仍然有缺点,上面的顺序是先HTML,然后Symbol,最后SensitiveWord,这三个构成一个过滤链条,如果有一天我需要把另一个过滤链条插入到这根链条中间,实现起来很麻烦。

    4.改进职责链模式

      

    package com.dingyu.ChainOfResponsibility;
    
    import java.util.ArrayList;
    import java.util.List;
    /**
     * 
     * @author dingyu
     *
     */
    public class FilterChain implements Filter {
    
        private List<Filter> filters = new ArrayList<Filter>();
    
        public void add(Filter filter) {
            filters.add(filter);
        }
    
        public List<Filter> getFilters() {
            return filters;
        }
    
        @Override
        public String doFilter(String msg) {
            for (Filter filter : filters) {
                msg = filter.doFilter(msg);
            }
            return msg;
        }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Client {
    //    private static List<Filter> filters = new ArrayList<Filter>();
    
        public static void main(String[] args) {
            String s = "<html>,o.o,和谐";
            // 链条1
            FilterChain chain1 = new FilterChain();
            chain1.add(new HTMLFilter());
            // 链条2
            FilterChain chain2 = new FilterChain();
            chain2.add(new HTMLFilter());
            chain2.add(new SensitiveWordFilter());
            // 链条2插到链条1后
            chain1.add(chain2);
            chain1.add(new SymbolFilter());
            s = chain1.doFilter(s);
            System.out.println(s);
            // filters.add(new HTMLFilter());
            // filters.add(new SymbolFilter());
            // filters.add(new SensitiveWordFilter());
            // for (Filter filter : filters) {
            // s = filter.doFilter(s);
            // }
            // System.out.println(s);
        }
    }

      建议debug , eclipse快捷键

    5. 职责链实现双向过滤  

      思路类似于递归,建议使用debug一步步调试。

    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 过滤器,doFilter处理msg字符串
     * 
     * @author dingyu
     *
     */
    public interface Filter {
        // public String doFilter(String msg);
        public void doFilter(Request request, Reponse reponse, FilterChain filterChain);
    }
    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 处理html符号 测试用的,逻辑不是很严谨
     * 
     * @author dingyu
     *
     */
    public class HTMLFilter implements Filter {
    
        @Override
        public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
            request.getRequestMsg().replace("<", "[").replace(">", "]");
            filterChain.doFilter(request, reponse, filterChain);
            reponse.setReponseMsg(reponse.getReponseMsg() + "-----HTMLFilter");
        }
    
        // @Override
        // public String doFilter(String msg) {
        // return msg.replace("<", "[").replace(">", "]");
        // }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 过滤敏感词汇
     * 
     * @author dingyu
     *
     */
    public class SensitiveWordFilter implements Filter {
    
        @Override
        public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
            request.getRequestMsg().replace("和谐", "/*河蟹*/");
            filterChain.doFilter(request, reponse, filterChain);
            reponse.setReponseMsg(reponse.getReponseMsg() + "-----SensitiveWordFilter");
        }
    
        // @Override
        // public String doFilter(String msg) {
        // return msg.replace("和谐", "/*河蟹*/");
        // }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    /**
     * 处理符号
     * 
     * @author dingyu
     *
     */
    public class SymbolFilter implements Filter {
    
        @Override
        public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
            request.getRequestMsg().replace("o.o", "^v^");
            filterChain.doFilter(request, reponse, filterChain);
            reponse.setReponseMsg(reponse.getReponseMsg() + "-----SymbolFilter");
        }
    
        // @Override
        // public String doFilter(String msg) {
        // return msg.replace("o.o", "^v^");
        // }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 
     * @author dingyu
     *
     */
    public class FilterChain implements Filter {
    
        private List<Filter> filters = new ArrayList<Filter>();
        private int index=-1;
    
        public void add(Filter filter) {
            filters.add(filter);
        }
    
        public List<Filter> getFilters() {
            return filters;
        }
    
        // @Override
        // public String doFilter(String msg) {
        // for (Filter filter : filters) {
        // msg = filter.doFilter(msg);
        // }
        // return msg;
        // }
    
        @Override
        public void doFilter(Request request, Reponse reponse, FilterChain filterChain) {
            if (index == filters.size()-1)
                return;
            index++;
            filters.get(index).doFilter(request, reponse, filterChain);
            
        }
    
    }
    package com.dingyu.ChainOfResponsibility;
    
    public class Client03 {
        public static void main(String[] args) {
            Request request = new Request();
            Reponse reponse = new Reponse();
            request.setRequestMsg("<html>,o.o,和谐");
            reponse.setReponseMsg("hahahahaha");
            FilterChain chain = new FilterChain();
            chain.add(new HTMLFilter());
            chain.add(new SensitiveWordFilter());
            chain.add(new SymbolFilter());
            chain.doFilter(request, reponse, chain);
            System.out.println(request.getRequestMsg());
            System.out.println(reponse.getReponseMsg());
        }
    }

     

    转载于:https://www.cnblogs.com/dddyyy/p/10032183.html

    展开全文
  • 整个设计模式领域还很新,本书的四位作者也许已占据了这个领域造诣最深的专家中的半数,因而他们定义模式的方法可以作为后来者的榜样。如果要知道怎样恰当定义和描述设计模式,我们应该可以从他们那儿获得启发”--steve...
  • 前言 设计模式填坑系列,紧接前文(距离上次写笔记又过去了一个多月,我也不知道怎么加班加着加着就一个月了-_-!) 正文 定义 工厂模式是指提供一个创建对象接口而不保留具体...(觉得我说太抽象没关系...
        

    前言

    设计模式填坑系列,紧接前文(距离上次写笔记又过去了一个多月,我也不知道怎么加班加着加着就一个月了-_-!)

    正文

    定义

    工厂模式是指提供一个创建对象的接口而不保留具体的创建逻辑,可以根据输入类型创建对象。让子类自行决定实例化哪一种工厂类,实际的创建对象过程在子类中进行。在创建相似子类的时候,执行重复操作。(觉得我说的太抽象没关系,马上就到举例子环节)

    具体实现

    前面的描述可能还是稍显抽象,举个游戏里面的例子,我们需要实现一个生产游戏角色的RoleMaker工厂,达到以下目的:

    var warrior = RoleMaker.factory('warrior')//生产一个战士
    var mage = RoleMaker.factory('mage')//生产一个法师
    var priest = RoleMaker.factory('priest')//生产一个牧师
    warrior.introduce()// 输出 '我是一个战士,我的特长是近战'
    mage.introduce()// 输出 '我是一个法师,我的特长是魔法'
    priest.introduce()// 输出 '我是一个牧师,我的特长是治疗'

    在这里,我们可以看到形如var warrior = RoleMaker.factory('warrior')的语句,就是使用RoleMaker工厂生产了一个战士的过程,这里的战士法师牧师都是角色的一个子类。

    接下来就是如何实现上面的RoleMaker类,最核心的思想还是原型链继承(忘记的同学请自行补课,磨刀不误砍柴工),具体的实现代码如下:

      //父类
      function RoleMaker() {
        // 这里是父类的属性
      }
    
      RoleMaker.introduce = function () {
        return '我是一个' + this.type + ',我的特长是' + this.specialty
      }
    
      //工厂方法
      RoleMaker.prototype.factory = function (type) {
        var role;
        // 这里我们直接把子类构造函数都保存在父类的静态属性中,这样的好处是不污染全局命名空间,同时方便查找。实际上当然也可以直接用`switch-case`实现
        if (typeof (RoleMaker[type]) !== "function") {
          //对未指定子类的处理,这里是直接抛出错误,也可以为未指定类型做默认值处理
          throw {
            name: 'Error',
            message: type + 'does not exist'
          }
        }
        if (typeof (RoleMaker[type].prototype.introduce !== "function")) {
          // 判断是否已经实现继承,注意只继承一次,当然由于只是原型链继承这里判断条件也可以用`RoleMaker[type].constructor===RoleMaker`
          RoleMaker[type].prototype = new RoleMaker()
        }
    
        role = new RoleMaker[type]() //实例化,也就是实际创建对象的过程
        return role
      }
    
      // 每个子类的构造函数
      RoleMaker.warrior = function () {
        this.type = "战士",
          this.specialty = "近战"
      }
      RoleMaker.mage = function () {
        this.type = "法师",
          this.specialty = "魔法"
      }
      RoleMaker.priest = function () {
        this.type = "牧师",
          this.specialty = "治疗"
      }

    以上代码比较简单,来回顾下前文说道的几个特点:

    1. 使用者只需要知道特定子类的名称就可以直接生产对应的子类,无需知道具体实现逻辑
    2. 实际的创建对象过程在子类中进行
    3. 在创建相似子类的时候,执行重复操作(每个子类只做一次的继承)

    补充一个实例

    实际上,js的Object()函数,就很符合工厂模式的特征:

    var n = Object(1)
    n.constructor === Number
    var s = Object('1')
    n.constructor === String
    var b = Object(true)
    n.constructor === Boolean

    小结

    自我感觉设计模式系列由于还是处于学习阶段,实践经验相对较少,所以写起来还是偏向于读书笔记类,所以可能有很多地方都显得粗糙。权当做先占个坑,等后续有更深入理解再回来补上。
    然后惯例感谢之前的热心读者,尤其是为我指出错误的小伙伴。
    然后依然是每次都一样的结尾,如果内容有错误的地方欢迎指出;如果对你有帮助,欢迎点赞和收藏,转载请征得同意后著明出处,如果有问题也欢迎私信交流,主页添加了邮箱地址~溜了

    展开全文
  • 机器学习指是让计算机从数据挖掘模式和特征,它大致分为监督学习和非监督学习。分类和回归是监督学习,我们需要用带标签样本去训练模型;聚类和降维是非监督学习,我们不需要使用带标签数据进行训练。 分类...
  • 在游戏,游戏人物根据玩家输入以及人物与游戏世界交互,会有许多动作动画效果转换。...而按键和动作并不是一一对应的关系,比如跳跃过程按下左右移动键,并不能绘制走路动画效果。 这些状态之间转换...
  • 之前在CentOS7通过yum安装mysql,那叫一个慢,200多Mb东西,每秒下载十几KB,这得下到猴年月去,好在因为i工作关系,之前买了ssr节点,就想着通过CentOS7代理,来实现加速访问国外服务器. 首先,我们需要在本地软件...
  • 到目前为止,我们所说固定型思维模式意味着你认为个人能力是固定,但在恋爱关系中,还要考虑两点,即你伴侣和感情本身。现在你固定型思维模式与三方面有关。你可以认为自己特质是固定,伴侣特质是固定...
  • 进程树图: 用树的模式显示进程列表,让您可以轻松了解父进程与子进程间的关系! 进程强杀: 软件运行于内核模式时可强杀任何进程,该功能对木马进程特有效! 进程守护: 当您想长时间运行某个程序时可用此功能守护该...
  • 而decorator模式中被包装者与decorator还是属于同一类对象,只不果通过decorator模式来增加一些额外其它功能.举个不是很恰当例子来描述adapter----、驴、骡子的关系:、驴可以说是两种不同抽象,他们有各自...
  • Protel DXP 是第一套完整的板卡级设计系统,真正实现在单个应用程序中的 集成。设计从一开始的目的就是为了支持整个设计过程,Protel DXP 让你可以 选择最适当的设计途径来按你想要的方式工作。Protel DXP PCB 线路...
  • CruiseYoung提供的带有详细书签的... 感谢这些朋友的建议推动了我,在这次培训中的另外一个收获就是,结识了本书的作者之一。  二、本书的内容  综合所有的稿件,我将这本书分成四篇,分别为:  1. DBA工作手记...
  • 最近一直做用户使用搜索引擎行为模式聚类的工作,开始尝试用K-means,效果非常不好,用户Session中的动作之间有较强   的关联,这种基于距离的聚类无法体现这种关系。继而,转向基于模型的聚类方法,而马尔可夫...
  • PowerShadow(影子系统)

    2008-10-25 07:53:32
    因为在影子硬碟中是不能档案储存, 所以如果在Single Shadow模式中, 建立了一诋档案想储存, 通常都会储存在其他分区中, 这样就算退出Shadow Mode, 返回原系统, 建立档案还会存在, 否则建立档案会自动消失....
  • 此外,本书还讨论了关于sql编程中查找表、视图、辅助表、虚拟表的应用,并独到地阐明了如何在sql系统中正确地处理时间值以及sql编程中的其他技术难点。  本书适合广大数据库编程人员和sql程序员学习参考。 作译者...
  • 1.2.8 对大数据平台中的元数据管理是怎么理解的,元数据收集管理体系是怎么样的,会对大数据应用有什么样的影响 1.2.9 你理解常见如阿里,和友商大数据平台的技术体系差异以及发展趋势和技术瓶颈,在存储和计算两...
  • 计算机实习日记

    2011-11-26 12:22:41
    技术部的软件安装维护工作虽然是企业部门运营的一个小侧面,但关系到企业在广大客户心目中的形象,关系到企业参与全国范围的计算机软件销售竞争的魄力及品牌亲和力。 虽然我之前对计算机软件这方面的知识有所了解,...
  • 经济学,

    2014-02-21 14:52:00
    经济学就成了社会科学之母,对我来说,马克思主义最引人入胜之处,在于它有一整套概念、工具、专有名词、术语,比如"物质基础"与"上层建筑"、"生产模式"与"生产关系"、"矛盾斗争"与"对立统一"等等。一旦掌握了这套...
  • 电脑蓝屏对照码

    2019-05-05 14:16:40
    表明在内核模式中存在以太高的进程内部请求级别(IRQL)访问其没有权限访问的内存地址. ◇解决方案:请用前面介绍的解决方案中的2、3、5、8、9方案尝试排除. 2、0x00000012:TRAP_CAUSE_UNKNOWN ◆错误分析:如果遇到这...
  • 后面是IDE设备类型和硬件参数,TYPE用来说明硬盘设备类型,我们可以选择AUTO、USER、NONE工作模式,AUTO是由系统自己检测硬盘类型,在系统存储了1-45类硬盘参数,在使用该设置值时不必再设置其它参数;...
  • AnkitFadia,生命中的里程碑:10岁——父母在家给他配置了一台个人电脑。12岁——表现出对计算机的超常天赋,成为无师自通的少年黑客。14岁——出版了第一本个人专著——AnUnOFFicialGuidetoEthicalHacking(良性...
  • 20 求职中的心理健康问题 20 大专生求职受歧视 21 这世界并不亏欠我们什么 23 求职中的正确态度 24 面试前充分准备 24 专注于真正的机会 25 五个步骤查实公司信息 26 筛选重点应聘目标 27 了解职位信息有的放矢 29 ...
  • WIN XP蓝屏代码大全

    2013-08-08 12:29:21
    表明在内核模式中存在以太高的进程内部请求级别(IRQL)访问其没有权限访问的内存地址. ◇解决方案:请用前面介绍的解决方案中的2、3、5、8、9方案尝试排除. 2、0x00000012:TRAP_CAUSE_UNKNOWN ◆错误分析:如果遇到这...
  • x-scan-v3.3-cn

    2013-09-23 21:36:56
    造成这个问题的原因可能有两种:第一种可能性是您的扫描器版本比较低,扫描器本身存在“千年虫”问题,对于返回的信息扫描器在判断的时候,会错误的以为时间信息2000年x月x日中的200是“文件存在”标志,这样就会...
  • 5.3.4 Database Control中的其他安全管理集成 199 5.4 UTL_程序包网络访问管理 199 5.4.1 UTL_*网络程序包的细粒度访问控制 200 5.4.2 Automatic Storage Management的sysasm权限 206 5.4.3 LOB加密增强 207 ...
  •  本书按照“发现问题→解决问题→实践与理论相结合”的方式进行介绍,首先对现实问题进行分析,然后提供合适的解决方案,最后自然地引出oracle中的理论知识点,这种讲解方法能够有效地降低阅读难度,帮助读者更好地...
  • 中文版Excel.2007图表宝典 2/2

    热门讨论 2012-04-06 19:01:36
    1.5.2 把内嵌图表转换成图表表单中的图表/18 1.5.3 复制图表/18 1.5.4 删除图表/18 1.5.5 添加图表元素/18 1.5.6 移动和删除图表元素/19 1.5.7 设置图表元素的格式/19 1.5.8 复制图表的格式/20 1.5.9 重命名图表/20 ...

空空如也

空空如也

1 2
收藏数 30
精华内容 12
关键字:

关系模式中的马