大话设计模式(带目录完整版)[中文PDF+源代码].zip

下载地址:http://pan.baidu.com/s/1giQP4
大话设计模式C++.pdf
下载地址:http://pan.baidu.com/s/1ABbBv
大话设计模式C++源码

下载地址:http://pan.baidu.com/s/1yzLBl

----------------------------------------------
刚刚看了访问者模式,复杂问题简单化。
class Node
{
 accept(Visitro *pVisitor);
}
class Visitor

{

apply(Node *pNode){pNode->fun();}

}

------------------------------------------------
url:http://greatverve.cnblogs.com/p/Design-patterns-down.html

访问者模式的目的:  封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。

问题的提出:System.Collection命名空间下提供了大量集合操作对象。平时我们大多在集合中都是存储的同类型对象,像2.0中的泛型中就规定集合中只能存储指定的对象类型,要么是整形要么是字符型等,否则会报错。如果针对一个保存有不同类型对象的聚集采取某种操作该怎么办呢?

示例:假设有一个员工报销的集合,里面存储了员工姓名和报销金额情况,而报销数据类型并不统一,有的是整形的,有的是双精度的,有的是字符串型,我们要做的就是根据具体的数据类型给出不同的显示格式,例如在整型数据后面加一个"C",(是我自己想的,整型的符号一时没想起来),在双数度数据后面加一个"D",浮点数据后面加"F",而字符串则什么也不加。

传统实现方式:遍历集合中的元素,判断元素类型,然后做相应的处理。代码如下:会发现就会出现必须对元素类型做类型判断的条件转移语句,如果判断多了,要想维护起来也并不容易。此时可考虑采用访问者模式。

ArrayList _arr = new ArrayList();
            _arr.Add("一百元");
            _arr.Add(100);
            _arr.Add(150.5);
            foreach  (object o in _arr )
            {
                if (o is string)
                {
                    Console.WriteLine(o.ToString());
                }
                else if (o is double)
                {
                    Console .WriteLine (o.ToString ()+" D");
                }
                else if (o is Int32)
                {
                    Console.WriteLine(o.ToString()+" C");
                }
            
            }

访问者模式适用性:

1:数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
           2:被访问的类结构非常稳定的情况下使用。系统很少出现需要加入新节点的情况。如果出现需要加入新节点的情况,那么就必须在每一个访问对象里加入一个对应于这个新节点的访问操作,而这是对一个系统的大规模修改,因而是违背"开一闭"原则的。

访问者模式的结构:

1:抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。

/// <summary>
    /// 抽象访问者(Visitor)角色
    /// </summary>
    abstract class Visitor
    {
        // Methods
        abstract public void Visit(Element element);
    }

2:具体访问者(ConcreteVisitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。

/// <summary>
    /// 具体访问者(ConcreteVisitor)角色
    /// 打印双精度数据
    /// 在数据后面加 D
    /// </summary>
    class DoubleVisitor : Visitor
    {
        // Methods
        public override void Visit(Element element)
        {
            Employee employee = ((Employee)element);
            if (employee._Data.GetType().ToString ()!="System.Double")
            { return; }
            Console.WriteLine("{0}'s data: {1}D",
              employee.Name, employee._Data );
        }
    }
    /// <summary>
    /// 具体访问者(ConcreteVisitor)角色2
    /// 打印整型数据
    /// 在数据后面加 C
    /// </summary>
    class Int32Visitor : Visitor
    {
        public override void Visit(Element element)
        {        
            Employee employee = ((Employee)element);
            if (employee._Data.GetType().ToString() != "System.Int32")
            { return; }
            Console.WriteLine("{0}'s data : {1}C",
              employee.Name, employee._Data );
        }
    }

3:抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参量。

/// <summary>
    /// 抽象节点(Node)角色
    /// </summary>
    abstract class Element
    {
        // Methods
        abstract public void Accept(Visitor visitor);
    }

4:具体节点(Node)角色:实现了抽象元素所规定的接受操作。

/// <summary>
    /// 具体节点(Node)角色
    /// </summary>
    class Employee : Element
    {
        // Fields
        string name;
        private object  _data;
        public object  _Data
        {
            get { return this._data ; }
            set { this._data  = value; }
        }
        // Constructors
        public Employee(string _name,object  t)
        {
            this.name = _name;
            this._Data  = t;
            
        }
        // Properties
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        // Methods
        public override void Accept(Visitor visitor)
        {
            visitor.Visit(this);
        }
    }

5:结构对象(ObiectStructure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集。

/// <summary>
    /// 结构对象(ObiectStructure)角色
    /// </summary>
    class Employees
    {
        // Fields
        private ArrayList employees = new ArrayList();
        // Methods
        public void Attach(Employee employee)
        {
            employees.Add(employee);
        }

public void Detach(Employee employee)
        {
            employees.Remove(employee);
        }
        public void Accept(Visitor visitor)
        {
            foreach (Employee e in employees)
                e.Accept(visitor);
        }
    }

6:客户端代码:

// Setup employee collection
            Employees e = new Employees();
            e.Attach(new Employee("用户A:", 25000.0));
            e.Attach(new Employee("用户B:", 10000));
            e.Attach(new Employee("用户C:", "45000.0RMB"));

// Create two visitors
            DoubleVisitor v1 = new DoubleVisitor();
            Int32Visitor v2 = new Int32Visitor();
            StringVisitor v3 = new StringVisitor();
            // Employees are visited
            e.Accept(v1);
            e.Accept(v2);
            e.Accept(v3);

结构对象会遍历它自己所保存的聚集中的所有节点,在本系统中只有一个节点Employee。这个访问是由以下的操作组成的:

1. Employee对象的接受方法Accept被调用;

2. Employee对象反过来调用访问者对象的Visit方法,并将对象本身传入;

3. 访问者对象调用本身的Visit方法。

 访问者模式有如下的优点:

1. 访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。

2. 访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。

3. 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。

4. 积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。

访问者模式有如下的缺点:

1. 增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。

2. 破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。

注:

本文引用:《Java与模式》

http://www.cnblogs.com/zhenyulu/articles/79719.html

《大话设计模式》C#/C++版pdf/源码下载的更多相关文章

  1. HTML5与CSS3实例教程(第2版) 附源码 中文pdf扫描版

    HTML5和CSS3技术是目前整个网页的基础.<HTML5与CSS3实例教程(第2版)>共分3部分,集中讨论了HTML5和CSS3规范及其技术的使用方法.这一版全面讲解了最新的HTML5和 ...

  2. 跟我学SpringMVC目录汇总贴、PDF下载、源码下载

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. DRF终极封装ViewSet和Router附教程PDF源码

    在DRF官方教程的学习过程中,一个很明显的感受是框架在不断地进行封装,我们自己写框架/工具/脚本/平台也可以模仿模仿,先完成底层代码,再做多层封装,让使用者很容易就上手操作.本文是教程的最后一篇,介绍 ...

  4. PureMVC(JS版)源码解析:总结

    PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写博客的过程中得到了些提升.我也是第一次写系列 ...

  5. PureMVC(JS版)源码解析

    PureMVC(JS版)源码解析:总结   PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写 ...

  6. 【Python】《大话设计模式》Python版代码实现

    <大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...

  7. 使用DevExpress的PdfViewer实现PDF打开、预览、另存为、打印(附源码下载)

    场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  8. 1-开发共享版APP(源码介绍)-BUG修复

    这一系列文章将介绍APP的源码,这一节作为所有BUG问题修复! https://www.cnblogs.com/yangfengwu/category/1512162.html    //开发共享版A ...

  9. 中秋礼物!开源即时通信GGTalk安卓版全新源码!

    经过连续两个多月的努力(开发.调试.测试.改bug),我们终于赶在中秋国庆之前能把全新的GGTalk Android版本献给大家. 4年之前我们就推出了GGTalk Android的第一个版本,但是功 ...

随机推荐

  1. 关于v4包的Fragment过渡动画的事件监听无响应问题解决

    项目中部分功能模块采用了单Activity+多Fragment模式,当Fragment切换时,需要在过渡动画执行完后做一些操作,通常就是在自己封装的FragmentBase中重写onCreateAni ...

  2. fish(自动推荐命令;语法高亮等)

    Fish 是 Linux/Unix/Mac OS 的一个命令行 shell,有一些很好用的功能. 自动推荐 VGA 颜色 完美的脚本支持 基于网页的配置 帮助文档自动补全 语法高亮 以及更多 自动推荐 ...

  3. WebBrowserのIEバージョンを最新にする。

    WindowsフォームでWebBrowserコントロールを配置すると.IEのバージョンが 7 と古い.レジストリをいじると.IE11の Edgeモードに変更できる(参考記事).デザイン画面でWebBr ...

  4. 浅谈JavaScript DDOS 攻击原理与防御

    前言 DDoS(又名"分布式拒绝服务")攻击历史由来已久,但却被黑客广泛应用.我们可以这样定义典型的DDoS攻击:攻击者指使大量主机向服务器发送数据,直到超出处理能力进而无暇处理正 ...

  5. Ubuntu出现apt-get: Package has no installation candidate问题

    今天在安装 vim 的时候出现了 Package 'vim' has no installation candidate的问题 解决方法如下:# apt-get update# apt-get upg ...

  6. Kmeans 聚类 及其python实现

    主要参考   K-means 聚类算法及 python 代码实现    还有  <机器学习实战> 这本书,当然前面那个链接的也是参考这本书,懂原理,会用就行了. 1.概述 K-means  ...

  7. Gitlab Webhooks, External Services, and API(二)

    一. 使用webhooks webhook 是一个API的概念,并且变得越来越流行.我们能用事件描述的事物越多,webhook的作用范围也就越大.webhook作为 个轻量的事件处理应用,正变得越来越 ...

  8. 判断js数组/对象是否为空

    /** * 判断js数组/对象是否为空 * isPrototypeOf() 验证一个对象是否存在于另一个对象的原型链上.即判断 Object 是否存在于 $obj 的原型链上.js中一切皆对象,也就是 ...

  9. 008 使用POJO对象绑定请求参数

    1.介绍 2.Person.java package com.spring.bean; public class Person { private String username; private S ...

  10. Django 2.1版本与Django 1.8.3的一些区别(转)

    Django 2.1版本与Django 1.8.3的一些区别     我在刚开始学习的时候使用的Django版本是1.8.3的,后来在安装其它软件的时候,可能需要2.1的版本,自动帮我更新了Djang ...