设计模式学习(二)

1·建造者模式

一、场景 

当需要生产一辆汽车时,我们需要为其装配发动机、轮胎、座椅等等部件,这个装配过程是比较复杂的而且也需要较高的组装技术。而建造者模式(Builder Pattern)就是为了将部件与组装分离开。

二、 概念 
  将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

  与抽象工厂的区别:在建造者模式里,有个指导者,由指导者来管理建造者,用户是与指导者联系的,指导者联系建造者最后得到产品。即建造模式可以强制实行一种分步骤进行的建造过程。

  建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心。

三、建造者模式结构组成

  • Product: 表示被构造的复杂对象,其中包含需要构建的部件属性。
  • Builder: 创建一个产品对象的各个部件指定抽象接口。
  • ConcreteBuilder: 实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示。
  • Director: 调用具体建造者角色以创建产品对象。              

理解

这个模式和抽象工厂模式很像,但是在外部增加了一个组装部分,将接口内的实现对象通过组装部分进行业务操作,之后由director来调用组装部分即可。

2·原型模式

当我们需要构建一个与已经存在对象相似时,再通过new去产生一个新对象需要非常繁琐的数据准备或访问权限,而这时就可以用到 原型模式 ,原型模式实现就是Java中的克隆技术,以某个对象为原型,复制出新的对象,显然新的对象具备原型对象相同的特点。 原型模式优点是,效率高,可以直接复制,避免了重新执行构造方法过程步骤 。 

  原型模式中的复制类似于new,但不同于new。new创建新的对象属性采用的是默认值,而复制出的对象的属性和原型对象属性完全相同。并且复制出的新对象的改变不会影响原型对象。然后再根据需要修改复制出的对象的值。

主要依赖Object类内的一个clone方法,但是这个方法是protect的,只能在lang包下被重写,而程序员写的代码是不能自己创建Java.lang包的,因此需要通过super.clone()来获取到这个方法的使用,还提供了一个Cloneable的类,这个类没有任何实现,但是实现了这个类会被系统默认为要创造克隆对象。

要注意一个深度克隆的问题:A的对象里引用了一个C对象,以及有D,F等属性和方法,B对A执行了克隆,则开辟新的内存空间对D,F进行重新的创建,AB的属性方法是相似的(内容相同,但地址不同),但他们对于C的引用,指向了同一个地址,而没有重新对这个C对象进行克隆,需要深度克隆的话,应该对C也进行一次clone();

3·适配器模式


目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。

需要适配的类(Adaptee):需要适配的类或适配者类。

适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。


4·代理模式

一)静态代理

实现方式:

a) 为真实类和代理类提供的公共接口或抽象类。(租房)

b) 真实类,具体实现逻辑,实现或继承a。(房主向外租房)

c)  代理类,实现或继承a,有对b的引用,调用真实类的具体实现。(中介)

d) 客户端,调用代理类实现对真实类的调用。(租客租房)

二)动态代理

实现方式:

a) 公共的接口(必须是接口,因为Proxy类的newproxyinstance方法的第二参数必须是个接口类型的Class)

b) 多个真实类,具体实现的业务逻辑。

c)  代理类,实现InvocationHandler接口,提供Object成员变量,和Set方法,便于客户端切换。

d) 客户端,获得代理类的实例,为object实例赋值,调用Proxy.newproxyinstance方法在程序运行时生成继承公共接口的实例,调用相应方法,此时方法的执行由代理类实现的Invoke方法接管。


jdk动态代理使用的局限性
通过反射类ProxyInvocationHandler回调接口实现的jdk动态代理,要求委托类必须实现一个接口,但事实上并不是所有类都有接口,对于没有实现接口的类,便无法使用该方方式实现动态代理。

5·组合模式

将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和复杂对象的使用具有一致性。

实现方式:

a)     抽象的构件接口 (规范执行的方法),b及c都需实现此接口,如:Junit中的Test接口

b)     叶部件(实现a,最小的执行单位),如:Junit中我们所编写的测试用例

c)     组合类(实现a并维护一个a的集合[多个b的组合]),如:Junit中的 TestSuite

d)     客户端 可以随意的将b和c进行组合,进行调用

什么情况下使用组合模式:

当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。

 

2.       策略模式

实现方式:

a)      提供公共接口或抽象类,定义需要使用的策略方法。(策略抽象类)

b)      多个实现的策略抽象类的实现类。(策略实现类)

c)       环境类,对多个实现类的封装,提供接口类型的成员量,可以在客户端中切换。

d)      客户端 调用环境类 进行不同策略的切换。

注:Jdk中的TreeSet TreeMap的排序功能就是使用了策略模式。

优点与缺点:

  (1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

  (2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

 

  (1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

  (2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值