更新时间: 试题数量: 购买人数: 提供作者:

有效期: 个月

章节介绍: 共有个章节

收藏
搜索
题库预览
依题意,在图1中,Duck为抽象类,描述了抽象的鸭子,方法fly()、quack() 和display()分别表示不同种类的鸭子都具有飞行特征、发声特征和外观特征;而类RubberDuck、MallardDuck、CottonDuck 和RedHeadDuck 分别描述具体的鸭子种类;类Fly Behavior与QuackBehavior 为抽象类,分别用于表示抽象的飞行行为与发声行为;类Fly NoWay与Fly WithWings分别描述不能飞行的行为和用翅膀飞行的行为;类Quack、Squeak 与QuackNoWay 分别描述发出“嘎嘎”声的行为、发出橡皮与空气摩擦声的行为和不发声的行为。鉴于不同的鸭子种类只是在行为方面有所区别,且为支持将来能够模拟更多种类鸭子的特征,该公司架构师最有可能采用策略(Strategy) 设计模式来设计如图1所示的模拟鸭子游戏软件。Strategy 模式定义了一组能够用来表示可能行为集合的类。这些行为可以在应用程序中使用,来修改应用程序功能。Strategy (策略)模式的设计意图是,定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化。具体而言,该模式是支持定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。Strategy 模式的一般结构如图2所示。Strategy 模式具有以下一些优点和缺点。 (1)另一种子类化方法。Strategy 类层次为Context (上下文)定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。可以直接生成一个Context 类的子类,从而给它以不同的行为。但这会将行为强制编制到Context 中,而将算法的实现与Context 的实现混合起来,从而使Context 难以理解、难以维护和难以扩展,而且还不能动态地改变算法。最后得到一堆相关的类,它们之间的唯一差别是它们所使用的算法或行为。将算法封装在独立的Strategy 类中使得架构师可以独立于Context 而改变它们,使它易于切换、理解和扩展。 (2)在类自身中定义了每一个行为,从而减少了一些条件语句:Strategy 模式提供了用条件语句选择所需行为以外的另一种选择。当不同的行为堆砌在一个类中时,很难避免使用条件语句来选择合适的行为。将行为封装在一个个独立的Strategy 类中消除了这些条件语句。 (3)更容易扩展,即在不对应应用程序进行代码修改的情况下,使该模式具有新的行为。 (4)客户必须了解不同的Strategy。 该模式有一个潜在的缺点,就是一个客户要选择一个合适的Strategy 就必须知道这些Strategy 到底有何不同。此时可能不得不向客户暴露具体的实现问题。因此仅当这些不同行为变成与客户相关的通信时,才需要使用Strategy 模式。 (5)Strategy 和Context 之间的通信用开销。无论各个ConcreteStrategy (具体策略)实现的算法是简单还是复杂,它们都共享Strategy 定义的接口。因此很可能某些ConcreteStrategy 不会都用到所有通过这个接口传递给它们的信息;简单的ConcreteStrategy 可能不使用其中的任何信息。这就意味着有时Context 会创建和初始化一些永远不会用到的参数。如果存在这样问题,那么将需要在Strategy 和Context 之间进行更加紧密的耦合。 (6)增加了对象的数目。Strategy 增加了一个应用中的对象的数目。有时可以将Strategy 实现为可供各Context 共享的无状态的对象来减少这一开销。任何其余的状态都由Context 维护。Context 在每一次对Strategy对象的请求中都将这个状态传递过去。共享的Strategy 不应在各次调用之间维护状态。【缺少答案,请补充】
在以下情况中,应该使用Strategy 模式。 (1)许多相关类只是在行为方面有所区别。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。 (2)需要使用一个算法的不同变体。例如,定义了一些反映不同的空间或时间权衡的算法,当这些变体实现为一个算法的类层次时,可以使用策略模式。 (3)算法使用客户端未知的数据,可使用策略模式以避免暴露复杂的、与算法相关的数据结构。 (4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy 类中以代替这些条件语句。 依题意,在图1中,需要考虑以下一些Strategy 模式实现问题。 (1)定义类Duck和类FlyBehavior (或类QuackBehavior) 接口。这些接口必须使得类FlyWithWings、类FlyNoWay、类Quack、类Squeak和类QuackNoWay 等能够有效地访问它所需要的Duck中的任何数据,反之亦然。一种解决办法是让类Duck将数据放在参数中传递给类FlyBehavior (或类QuackBehavior) 操作,也就是说,将数据发送给类FlyBehavior (或类QuackBehavior)。 这使得类FlyBehavior (或类QuackBehavior) 和类Duck 解耦。但从另一个角度考虑,类Duck 也可能发送一些类FlyBehavior (或类QuackBehavior) 不需要的数据。 另一种解决办法是让类Duck将自身作为一个参数传递给类FlyBehavior (或类QuackBehavior), 该 类FlyBehavior (或类QuackBehavior) 再显式地向类Duck 请求数据;或者类FlyBehavior (或类QuackBehavior) 可以存储对它的类Duck 的一个引用,这样根本不再需要传递任何东西。这两种情况下,类FlyBehavior (或类QuackBehavior) 都可以请求到它所需要的数据。但要求类Duck必须对它的数据定义一个更为精细的接口,这将使得类FlyBehavior (或类QuackBehavior) 和类Duck更加紧密地耦合在一起。 (2)将类FlyBehavior (或类QuackBehavior) 作为模板参数。例如,在C++中,可利用模板机制用一个Strategy 来配置一个类。然而这种技术仅当下被配置的类(如Duck) 被定义在编译时选择Strategy;它无须在运行时改变。在这种情况下,要被配置满足才可以使用:可以定义为以一个Strategy 类作为一个参数的模板类。使用模板不再需要定义给类FlyBehavior (或类QuackBehavior) 定义接口的抽象类。把类FlyBehavior (或类QuackBehavior) 作为一个模板参数也使得可以将一个类FlyBehavior (或类QuackBehavior) 和它的类Duck 静态地绑定在一起,从而提高效率。 (3)尽量使类FlyBehavior (或类QuackBehavior) 成为可选的对象。即使在不使用额外的FlyBehavior (或类QuackBehavior) 对象的情况下,类Duck 也还有意义,那么它还可以被简化。类Duck 在访问类FlyBehavior (或类QuackBehavior) 前先检查它是否存在,如果有,那么就使用它;如果没有,那么类Duck执行默认的行为。这种方法的好处是客户根本不需要处理FlyBehavior (或类QuackBehavior) 对象,除非它们不喜欢默认的行为。【缺少答案,请补充】
设计模式主要用于得到简洁灵活的系统设计,GoF的书中共有23个设计模式,这些模式可以按两个准则来分类:一是按设计模式的目的划分,可分为创建型、结构型和行为型3种模式;二是按设计模式的范围划分,即根据设计模式是作用于类还是作用于对象来划分,可分为类设计模式和对象设计模式,如表所示。 创建型模式是对对象实例化过程的抽象,它通过采用抽象类所定义的接口,封装了系统中对象如何创建及组合等信息。该模式允许在系统中创建对象,而不需要在代码中标识特定类的类型,这样用户就不需要编写大量复杂的代码来初始化对象。它是通过该类的子类来创建对象的。但是,这可能会限制在系统内创建对象的类型或数目。创建型模式主要有Factory Method(工厂方法)、Abstract Factory(抽象工厂)、Builder (构建器)、Prototype (原型)和Singleton (单独)等模式。 结构型模式主要用于如何组合已有的类和对象以获得更大的结构,一般借鉴封装、代理或继承等概念将一个或多个类或对象进行组合和封装,以提供统一的外部视图或新的功能。该模式允许在不重写代码或自定义代码的情况下创建系统,从而使系统具有增强的重复使用性和应用性。该模式控制了应用程序大部件之间的关系,将以不同的方式影响应用程序的结构。结构型模式主要有Adapter (适配器)、Bridge (桥接)、Composite (组成)、Decorator (装饰)、Fagade (外观)、Flyweight (享元)和Proxy (代理)等。 行为型模式主要用于对象之间的职责及其提供的服务的分配,它不仅描述对象或类的模式,还描述它们之间的通信模式,特别是描述一组对等的对象怎样相互协作以完成其中任意一个对象都无法单独完成的任务。该模式可以影响一个系统的状态和行为流。通过优化状态和行为流转换及修改的方式,可以简化、优化并且提高应用程序的可维护性。行为型模式主要有Interpreter (解释器)、TemplateMethod (模板方法)、Chain of Responsibility(职责链)、Command (命令)、Iterator (迭代器)、Mediator (中介者)、Memento (备忘录)、Observer (观察者)、State (状态)、Strategy (策略)和Visitor (访问者)等。【缺少答案,请补充】
这是一道要求读者掌握Java企业应用框架层次结构及其各层功能的简答题。本题所涉及的知识点如下。 (1)Java 企业应用框架一般被划分为表现层、业务逻辑组件层和持久层等3个逻辑层次。 (2)其中,表现层用来建立应用系统的界面,对应视图(View)。该层集中于为从客户端发来的请求服务的对象及行为,用于展现数据;负责使组件实现视图在JSP显示粒度、页面跳转,以及事件触发等功能。例如,表现层采用JSF(Java Server Face)JSP的开发流程的核心是事件驱动,组件和标签的封装程度非常高,很多典型应用已经不需要开发者去处理HTTP,整个过程是通过IoC (依赖注入)来实现的,即可以帮助对客户端请求进行先期及后期的处理等。 (3)业务逻辑组件层用来开发应用逻辑,对应控制器(Controller)。例如,业务逻辑组件层采用EJB3.0的Session Bean。EJB 3.0允许开发者使用耦合松散的组件来开发应用,实现一个EJB所有使用的类和接口都减少了。 该层集中于支持由表现层发起的(某些情况下也可能由持久层直接发起)业务数据的逻辑处理。例如,隐藏业务对象的复杂性,集中工作流的处理;分离表现层与持久层,并为服务提供外观和代理接口等。 (4)持久层是实现持久化存储,对应模型(Model)。例如,采用EJB 3.0实体Bean持久化模型,吸收了Hibernate 的一些思想采用O/R Mapping模式。 该层集中于支持持久资源通信。例如,与数据库交互数据;抽象数据源,提供透明的数据访问;帮助进行EJB组件中的异步处理等。【缺少答案,请补充】
这是一道要求读者掌握Struts、Spring 和Hibernate 轻量级开源框架特点和结合方式的简答题。本题所涉及的知识点如下。 (1)由于EJB容器能够很好的处理系统性能、事务机制、安全访问权限,以及分布式运算等问题,基于EJB框架进行开发能够保证企业应用平滑发展,而不是发展到一种规模就重新更换一套软件系统,且可以保证开发人员将大部分精力集中在业务逻辑的开发上。采用EJB框架开发的企业应用具有必须继承或依赖EJB容器的特点。EJB充分考虑到了顶级大型项目的需求,使用它几乎能解决企业级应用涉及的所有问题,相应的基于EJB框架也是一个功能复杂的重量级框架。 (2)在基于POJOs 轻量级框架上开发的应用程序无须依赖于EJB容器可独立运行,对应于Java企业应用3个层次的轻量级框架技术分别都得到了一定的发展。Struts 框架+Spring 框架+Hibernate 框架实现了表现层、业务逻辑组件层和持久层的结合。 (3)目前比较流行的开源层框架主要有Struts 和Tapestry。其中,Struts 是基于模型一视图控制器(MVC)模式的开源框架,主要用于企业应用中表示层的实现。借助于Struts,开发人员可以把主要精力集中在业务处理上,简化遵循MVC设计模式的Web应用开发工作,很好地实现代码重用,提高开发效率。 Struts 框架包括:①模型(Model)。在Struts 中模型是一个Action 类,开发者通过其实现商业逻辑,同时用户请求通过控制器向Action 的转发过程是基于由Struts - config.xml 文件描述的配置信息的。②视图(View)。视图是由与控制器配合工作的一整套JSP定制标签库构成,利用它们可以快速建立应用系统的界面。③控制器(Controller),本质上是一个Servlet,将客户端请求转发到相应的Action 类。④一堆用来做XML文件解析的工具包。 Struts 应用框架由于出现时间早,因此使用相对广泛,很容易找到很多现成的开源功能标签以供使用,以及样例程序可供参考。但是它的组件在页面中显示的粗粒度,以及框架类的限制在很多情况下会表现得过于死板,给表示层的开发会带来一些额外的代码开销。 Tapestry 与之不同的是,它是基于组件,而不是面向脚本语言(比如JSP和Velocity)的,组件是由一个定义文件(以XML的格式)、一个HTML 模板和一个Java 类构成的。 (4)Spring 是业务组件层轻量级框架。Spring 框架是一个基于IoC (依赖注入)和AOP(面向方面编程)的构架。用户可以通过Spring 来利用普通Java 对象(POJO)编程,使用依赖注入解析POJO间的依赖性,然后使用面向方面编程(AOP) 将服务与它们相关联。采用依赖注入使得它可以很容易地实现Bean的装配,提供了简洁的AOP并据此实现事务管理等,但是它不具备处理应用分布式的能力。Spring 的核心要点是支持不绑定到特定J2EE服务的可重用业务和数据访问对象。这样的对象可以在不同的J2EE 环境(Web 或EJB)、独立应用程序和测试环境之间重用。 Spring 框架处于应用服务器和服务库的上方,服务整合的代码属于框架,并暴露于应用开发者。 它与应用服务器整合的能力相对EJB 3.0要弱。但是Spring 框架模块的可分离配置体现了它优于EJB 3.0的灵活性。 (5)持久层框架主要有Hibernate 和各种JDO产品,以及iBATIS 等。其中,Hibernate 是一个开源的O/R Mapping框架,它对JDBC 进行了非常轻量级的对象封装,可以应用在任何使用JDBC的场合,可以在应用EJB的J2EE 框架中取代CMP,完成数据持久化的重任。相对而言,Hibernate基本优势表现在:使用Java 反射机制而不是字节码增强程序来实现透明性;使用简单;映射的灵活性很出色,它支持各种关系数据库,从一对一(1:1)到多对多(n:n) 的各种复杂关系。其缺点是限制所使用的对象模型(例如,一个持久性类不能映射到多个表)。 iBATIS 是一个简易的SQL Map工具,它是将手工编写的在XML配置文件中的SQL语句映射成Java对象。使用iBATIS 提供的O/R Mapping机制,对业务逻辑实现人员而言,面对的是纯粹的Java对象,这一层与通过Hibernate 实现O/R Mapping而言基本一致,而对于具体的数据操作,Hibernate 会自动生成SQL语句,而iBATIS 则要求开发者编写具体的SQL语句。相对Hibernate等“全自动”O/R Mapping机制而言,iBATIS 以SQL 开发的工作量和数据库移植性上的让步,为系统设计提供了更大的自由空间。作为“全自动”ORM实现的一种有益补充,iBATIS 的出现显得别具意义。
这是一道要求读者对比轻量级框架与重量级框架解决问题的侧重点的综合理解题。本题所涉及的知识点如下。 (1)设计与性能是实际框架选择的两个基本点,善于平衡才是框架选择的主要宗旨。轻量级框架和重量级框架解决问题的侧重点是不同的。 (2)轻量级框架侧重于减小开发的复杂度,相应的它的处理能力便有所减弱(如事务功能弱、不具备分布式处理能力),比较适用于开发中小型企业应用。采用轻量级框架后,一方面因为采用基于POJOs的方式进行开发,使应用不依赖于任何容器,这可以提高开发调试效率;另一方面轻量级框架多数是开源项目,开源社区提供了良好的设计和许多快速构建工具,以及大量现成可供参考的开源代码,这有利于项目的快速开发。例如,目前Tomcat + Spring + Hibernate 已经成为许多开发者开发J2EE 中小型企业应用偏爱的一种架构选择。 (3)作为重量级框架的EJB框架则强调高可伸缩性,适用于开发大型企业应用。在EJB体系结构中,一切与基础结构服务相关的问题和底层分配问题都由应用程序容器或服务器来处理,且EJB容器通过减少数据库访问次数及分布式处理等方式提供了专门的系统性能解决方案,能够充分解决系统性能问题。 (4)轻量级框架的产生并非是对重量级框架的否定,在某种程度上可以说二者是互补的。轻量级框架旨在开发具有更强大、功能更完备的企业应用;而EJB3.0 规范则在努力简化J2EE的使用,以使得EJB不仅仅是擅长处理大型企业系统,也利用开发中小型系统,这也是EJB轻量化的一种努力。对于大型企业的应用及将来可能涉及能力扩展的中小型应用,结合使用轻量级框架和重量级框架也不失为一种较好的解决方案。【缺少答案,请补充】
1