学习设计模式 (一)(总结)

来源:互联网 发布:java打印等腰杨辉三角 编辑:程序博客网 时间:2024/05/18 02:33

1.策略模式 


策略模式义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。

(把变化的事物和不变化的事物进行分类和分组,抽象出变化的事物成接口的形式, 然后在把每个变化的事物具体实现)

类图:



环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法。


2.观察者模式


观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。(特点:1对N)


消息发表者(Subject):registerObserver()添加订阅者,unregisterObserver()注销订阅者,notifyObserver()通知消息更新

消息订阅者(Observer):notify()消息更新


3.装饰者模式

装饰者模式:在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象



(*具体主体和装饰主体都可以有中间层)


装饰者模式类图:


4.单例模式


单例模式保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
(多线程情况下的资源的同步问题,解决方法1.synchronized;2.急迫创建;3,双重判断锁。

5.工厂模式

简单工厂模式(simple factory)是类的创建模式,又叫静态工厂方法(static factory method)模式。

简单工厂模式就是由一个工厂类根据传入的参数决定创建哪一种的产品类。
有4个角色
工厂类角色:是具体产品类角色直接调用者。 


抽象产品角色:接口或抽象类,负责具体产品角色的定义,及与客户端的交互。 

具体产品角色:被工厂类创建的对象,也是客户端实际操作对象。 

客户端:调用工厂类产生实例,并调用实例的方法进行相应工作。



工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。

 首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。   

工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。   

工厂方法模式(Factory Method pattern)是最典型的模板方法模式(Templete Method pattern)应用。



抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。

抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。



每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。




6.命令模式

命令模式:将请求、命令、动作等封装成对象。这样可以让项目使用这些对象来参数化其他对象。使得命令的请求者和执行者解耦



命令模式的结构

        顾名思义,命令模式就是对命令的封装,首先来看一下命令模式类图中的基本结构:

  • Command类:是一个抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令。
  • ConcreteCommand类:Command类的实现类,对抽象类中声明的方法进行实现。
  • Client类:最终的客户端调用类。

        以上三个类的作用应该是比较好理解的,下面我们重点说一下Invoker类和Recevier类。

  • Invoker类:调用者,负责调用命令。
  • Receiver类:接收者,负责接收命令并且执行命令。

        所谓对命令的封装,说白了,无非就是把一系列的操作写到一个方法中,然后供客户端调用就行了,反映到类图上,只需要一个ConcreteCommand类和Client类就可以完成对命令的封装,即使再进一步,为了增加灵活性,可以再增加一个Command类进行适当地抽象。

    如果使用命令模式,就要引入调用者、接收者两个角色,原本放在一处的逻辑分散到了三个类中,设计时,必须考虑这样的代价是否值得。

7.适配器模式

适配器模式(Adapter)将一个类的接口转换成客户希望的另外一个接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

适用场景:

1、已经存在的类的接口不符合我们的需求;

2、创建一个可以复用的类,使得该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作;

3、在不对每一个都进行子类化以匹配它们的接口的情况下,使用一些已经存在的子类。

通用类图:


对象适配器:

类适配器:

对象适配器和类适配器使用了不同的方法实现,对象适配器使用组合,类适配器使用继承。

装饰者模式和适配器模式的差异:

1.装饰者模式中装饰者和被装饰者都扩展于相同的超类,可以相互嵌套;适配器模式是实现了目标接口的子类,即适配器在嵌套时每个适配器都是属于不同的类。
2.适配器和装饰者在类图上是不一样的。
3.功能上适配器定义是一种接口转换成另一种接口;而装饰者模式是在原有的基础上要添加功能。


8.外观模式


外观模式:一个子系统的外部与其内部的通信通过一个统一的外观类进行,外观类将客户类与子系统的内部复杂性分隔开,使得客户类只需要与外观角色打交道,而不需要与子系统内部的很多对象打交道。
外观模式的结构图:


  (1) Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。

  (2) SubSystem(子系统角色)在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。


外观模式和命令模式的各自侧重点:

外观模式是通过一个高层接口来暴露其功能,而忽略其功能内部的细节;侧重点是是系统对外接口的简化,使内外解耦。命令模式的侧重点是把命令包装成对象,通过分装和组合来实现各个功能。

外观模式和适配器模式的差异:

适配器模式是把一个类或对象转换成另一种形式,而外观模式是一个系统对外功能的简化



0 0
原创粉丝点击