Java中的程序具有多种设计模式,粗略算下来,最常用的包括六种面向可复用性的模式:适配器模式、装饰器模式、外观模式、策略模式、模板模式、迭代器模式;以及六种面向可维护性的构造模式:工厂方法模式、代理模式、观察者模式、访问者模式、状态模式和备忘录模式。这十二种模式各有千秋,既相互联系又有所区别,在程序设计中发挥着极其重要的作用。
适配器模式和代理模式有一些相同之处,适配器和代理两种模式是第一对容易被混淆的模式。二者都采用了在原有函数外再加一层接口的方式进行设计。但是,它们的设计目的不同,因此在实际操作中也就有所差别。适配器模式主要是解决客户端能够给出的参数与函数实际参数不兼容的问题,因此,适配器模式设计出的函数与原函数的参数往往不同,它会在函数内先对参数进行处理,然后调用原有函数获取结果。而代理模式主要是解决构造实际问题,不管有什么原因,采用代理模式的理由只有一个——我不想早早地加载某个对象。因此就加载一个代理对象,在需要的时候再加载实际对象。因此代理对象和实际对象的参数必须相同。而将加载实际对象的代码放入需要访问实际对象的函数中。因此二者最重要的差别是参数。适配器模式的参数与原参数往往不同,代理模式则必须相同。
第二对容易被混淆的模式是策略模式和外观模式,因为二者都使用了选择的机制。但是,二者最关键的不同是选择的对象。策略模式的选择侧重于算法,因此它的操作是类或方法功能相同,但是实现方法不同如ArrayList和LinkedList的差距。而外观模式是采用统一的接口去访问不同的类,类或方法的功能不一定相同,例如创建文件,类1创建txt文件,类2创建mp4文件,二者功能不同,这时就应采用外观模式。
第三对容易被混淆的模式是观察者模式和访问者模式,二者都采用了委托机制。但是二者有一点明显不同,那就是委托的方向。访问者模式是这十二种模式中唯一一种采用双向委托机制的模式。访问者模式由两大模块组成,第一块是元素类,元素类中提供一个accept方法。第二块是访问者类,访问者类中提供visit方法。元素类中accept方法的参数是访问者类型的,用于确定是否接受参数中访问者对象的访问。访问者类中visit方法的参数是元素类型的,用于确定访问哪种元素。这样就实现了双向的委托。但是有一点,accept的实现是利用visit方法统一实现的,也就是说对于所有的accept方法,它们的方法体都相同。真正的差异在于visit方法,访问者类使用重载技术,为不同参数的visit方法给出不同的实现。也就是说访问的主动权在于访问者类,元素类只决定它接受还是不接受访问。观察者模式可以是双向委托:主体利用观察者名单确认可以被哪些观察者观察。观察者利用主体名单确认可以观察哪些主体;也可以是单向委托:主体可以利用观察者名单确认可以被哪些观察者观察。观察者没有主体名单确认可以观察哪些主体。主体提供attach方法进行绑定,提供detach方法解绑,提供notify方法用以通知观察者,具体实现是调用观察者类中的update方法。观察者提供update方法用以观察状态。
其余六种模式特点鲜明,不易混淆。工厂模式也存在选择,但是它选择的是生成对象的类型,统一使用所有类型的父类返回,特别注意的是抽象工厂模式的捆绑,在同一个选择中实现对两种类型对象的创建而且固定这两种类型对象的种类以防止错配。装饰器模式主要是实现抽象装饰类,其次是将抽象装饰类进行扩展实现具体装饰类,然后将被装饰类作为装饰类的属性进行装饰,可以将已装饰的类当做被装饰类使用,进而使用递归实现。模板模式在抽象模板类内实现步骤方法,规定各个对象相关的方法之间的执行顺序,而将与对象相关的方法放入具体类中实现。迭代器模式首先实现一个Iterable接口,获取Iterator类,同时实现Iterator接口获得Iteraor类。状态模式将程序分为控制模块和状态模块,状态模块用于表示状态和状态对应的操作,包括状态转移操作。控制模块实现了对状态转移方法的调用,进而实现状态转移。备忘录模式使用三个模块:Operation模块:用于创建备忘录及实现保存、恢复状态。Momento模块,用于设置和查询状态,创建信息单元。Caretaker模块,是具体实现,维护一个用于保存Momento模块创建的信息单元列表,实现信息单元的添加与删除。Operation模块的操作委托给Momento模块,Momento模块的操作委托给Caretaker模块。
Java程序设计模式要点及易混辨析
最新推荐文章于 2025-03-20 23:38:45 发布