- 1、本文档共483页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
* 每种新报表都可以作为一个新的访问者编写。 增加新的报表只需要加新的访问者方法。 组合模式的递归: 在Assembly的accept函数的实现中,会调用访问者的visit方法以及它所包含的所有Part实例的accept方法。这样,就遍历了整个层次结构树。 访问者模式与组合模式的结合: 对树中的每个结点,都会调用报表对象的相应visit函数。报表对象收集了必要的统计数据, visit就可以向报表对象询问感兴趣的数据并把它们呈现给使用者。 效果: 该结构允许我们在完全不影响Part层次结构的情况下创建任意数目的报表。此外,每个报表类都可以独立于所有其他报表类编译和分发。 * public interface Part { public String getPartNumber () ; //PartNumber此处是ID的含义 public String getDescription(); public void accept(PartVisitor v); } public class Assembly implements Part { public Assembly(String partNumber, String description) { itsPartNumber = partNumber; itsDescription = description; } * 思考: 为什么在Visitor类中只处理每个节点,而在Part类中做递归。能否在Visitor类中做递归,在Part类的Assembly实现类,accept函数做一个简单的非递归调用visit函数。 * 一般来说,如果一个应用程序中存在有需要以多种不同方式进行解释的数据结构,就可以使用Visitor模式。 编译器通常创建一些中间数据结构来表示那些语法上正确的源代码。然后,这些数据结构被用来生成经过编译的代码。有人会设想出针对每种不同的处理器或者优化方案的访问者。同样也有人会设想出把中间数据转换成交叉引用列表,甚至UML图的访问者。 很多应用程序都使用配置数据结构。有人会设想让不同的应用程序子系统通过使用它们自己特定的访问者遍历配置数据来对自己进行初始化。在每个使用访问者的情况中,所使用的数据结构都独立于它的用途。可以创建新的访问者,可以更改现有的访问者,并且可以把所有的访问者重新部署到安装地点而不会引起现有数据结构的重新编译和重新部署。这就是VISITOR模式的威力。 * 问题: 考虑前面的Modem层次结构。假设有一个具有很多使用者的应用程序。每个使用者都可以坐在他的计算机前,要求系统使用该计算机的调制解调器呼叫另一台计算机。有些用户希望听到拨号声,有些用户则希望他们的调制解调器保持安静。 * 设计方案: 可以通过在代码中每一处,对调制解调器拨号的地方询问使用者的优先选择来实现这一点。 如果使用者希望听到拨号声,我们就将扬声器的音量设高。否则,我们就把它关掉。 客户端代码: Modem m = user.getModem(); If (user.wantsLoudDial()) m.setVolume(ll); m.dial(...); * 改善: 另一种方法是在调制解调器对象内部设置一个标志,让dial方法检测这个标志并相应地设置音量。 public class HayesModem implements Modem private boolean wantsLoudDial = false; public void dial(...) { if (wantsLoudDial) setVolume(ll); } 缺陷: 这样做虽然好了一些,但是仍然必须在Modem每个的派生类中重复这一段代码。Modem新派生类的编写者必须要记着复制这段代码。依赖于程序员的记忆力是相当冒险的事。 * 改善: 可以使用TEMPLATE METHOD模式来解决这个问题: 把Modem从接口变成一个类,让它包含一个wantsLoudDial变量,并在dial函数中先检测完该变量后再去调用dialForReal函数。 public abstract class Modem private boolean wantsLoudDial = false; public. void dial(...) { if(wantsLoudDial) setVolume(ll); dialForReal(...); } public a
您可能关注的文档
- (精)论阿里巴巴的营销策略.ppt
- (精)论述文阅读客观题错项例说课堂.ppt
- (精)论坛营销的方式与种类.ppt
- (精)论语 名句.ppt
- (精)论语_名句及孔子颁奖词.ppt
- (精)论语十二章.ppt
- (精)萝卜谣课件.ppt
- (精)逻辑函数的运算和卡诺图.ppt
- (精)裸眼3D手机HTC-EVO_3D介绍.ppt
- (精)铝制压力容器.ppt
- 2024-2025学年安徽省亳州市涡阳县高二下学期2月开学考试政治试题(解析版).docx
- 2024-2025学年江西省赣州市上犹县高二下学期开学考试政治试题(解析版).docx
- 2024-2025学年山东省济宁市高二下学期开学考试政治试题(解析版).docx
- 2024-2025学年山西省卓越联盟高三下学期2月开学质量检测政治试题(解析版).docx
- 2024-2025学年新疆乌鲁木齐市高二下学期2月开学考试政治试题(解析版).docx
- 2024-2025学年新疆维吾尔自治区乌鲁木齐地区高三2月大联考文科综合政治试题(解析版).docx
- 2024-2025学年安徽省蚌埠市固镇县高一上学期1月期末考试政治试题 (解析版).docx
- 2024-2025学年江苏省扬州市高三上学期期末检测政治试卷(解析版).docx
- 2024-2025学年江西省吉安市高三上学期期末教学质量检测政治试题(解析版).docx
- 2024-2025学年山东省济宁市高二上学期1月期末考试政治试题(解析版).docx
文档评论(0)