网站建设过程报告,陈铭生简介,福田商城网站建设,如何提高自己在百度的排名经典的23种设计模式种属于结构型设计模式的是装饰模式#xff0c;适配器模式#xff0c;代理模式#xff0c;组合模式#xff0c;桥接模式#xff0c;外观模式#xff0c;享元模式。
如果说创建型设计模式解决的是创建对象的问题#xff0c;那么结构型模式就是通过类和…经典的23种设计模式种属于结构型设计模式的是装饰模式适配器模式代理模式组合模式桥接模式外观模式享元模式。
如果说创建型设计模式解决的是创建对象的问题那么结构型模式就是通过类和对象的组合解决开发过程中的老代码功能扩展通过代码结构设计降低代码耦合针对扩展开放针对改变关闭新老功能适配减少递归函数使用减少内存使用提高代码性能等等 废话讲了太多直接上干货-各结构型设计模式的本质 首先我想把装饰模式和代理模式放在一起讲 有没有人发现透明模式的装饰模式和运用组合思想实现的静态代理非常相识但是本质上有很大区别这种区别其实也是装饰模式与代理模式的本质区别其实说到底两者都在给原有代码做功能扩展的事但是它们所作用的维度不一样装饰模式装饰模式要求装饰器和被装饰对象都实现相同的接口或抽象类这也是它实现装饰链的基础可以通过包装(decorating)对象来扩展其功能同时保持对象接口不变使用组合的方式将装饰器对象嵌套在被装饰对象之中形成一个装饰器链。装饰模式半透明类图主要是在通过拓展具体装饰类来实现对象功能的扩展而代理模式更倾向于用一个通用功能来给目标类做功能扩展举个反例现在已有一个运用组合思想实现的静态代理类来给老功能做逻辑扩展后面发现新的需求需要新的扩展逻辑那我们就要再去重新写一个静态代理类然后后面发现新需求又来了又要再重新添加扩展逻辑在写一个静态代理类该死的新需求老是需要新的扩展逻辑这样导致我们针对同一个类写了好多代理类发现这么多静态代理类特别难管理,没法对代码的规范方法命名什么做限制很明显这种功能扩展的场景很不适合用静态代理模式相反这种新需求累加的情况 非常适合用具有的组合性特点的装饰模式【动态代理模式就更不用说了两种动态代理模式jdk动态代理基于字节码生成通过在运行时动态创建一个实现代理接口的匿名类来实现代理与cglib动态代理通过生成目标类的子类来实现代理本质都是运行时切面编程在给一个固定的扩展逻辑动态创建更多的代理类来适配更多的目标类只要你愿意的话你可以将代理生成器中的目标类设置成Object】 其实代理模式只是不太适合给代码逻辑扩展比较频繁的场景做功能扩展但是他又的确是代码功能扩展的一剂良药基本没有什么前置设计限制除了jdK动态代理的目标类有个必须是接口实现类的限制和cglib动态代理的目标类不可是final类的限制装治疑难杂症静态代理基本是想收拾谁收拾谁当然最好是被代理类能实现一个接口或继承某个抽象类这样更易于静态代理的逻辑复用以及遵循依赖倒置原则动态代理更是在rpc远程调用延迟加载日志记录权限控制等等方面应用广泛虽然会有些代价比如上面说代理类的增加以及动态代理反射机制代理的性能开销 上面我们主要讲了装饰模式与代理模式使用场景维度的区别一个是装饰类强调的拓展逻辑的维度另一个是代理类强调的逻辑复用的维度。 接下来我们讲讲桥接模式将一个类的抽象部分与其实现部分分离使它们可以独立地变化简单讲就是设计之初就考虑到抽象类的非抽象方法的可变逻辑将可变逻辑提取出来用接口属性中的方法去执行这样就不需要通过不断的继承重写父类方法来实现逻辑拓展注意这就是它本质解决的问题两种桥接模式构造注入桥接模式与set注入桥接模式构造注入桥接模式通过构造方法注入接口单纯从调用者角度上看起来是否有点像继承的思想实现的静态代理但其实正好相反构造注入桥接模式是往目标类里构造注入接口实现对象而继承的思想实现的静态代理是在代理类中通过构造被代理的父类对象并通过重写父类方法加扩展逻辑的方式在来实现对被代理父类对象的逻辑扩展注意这里大家重点观察扩展逻辑写在哪构造注入桥接模式自然是写在接口实现类中而继承的思想实现的静态代理的扩展逻辑是写在代理类中啊这样看来很明显对象桥接模式强调的是拓展逻辑的维度同时应该注意构造注入桥接模式构造方法传递的只能是接口而这种构造方式往往在抽象父类的构造方法中写死而继承的思想实现的静态代理传递的是被代理对象构造方法需要的值甚至可以是无参构造毕竟子类可以继承父类的所有方法可以很方便的通过重写来实现逻辑扩展构造注入桥接模式其实就是通过构造注入的方式实现接口属性的注入而set注入桥接模式采用set注入的方式实现接口属性的注入这也是两种桥接模式的本质区别但这并不影响set注入桥接模式在拓展逻辑上应用反而使得代码变的更加灵活构造注入只能在对象创建前注入而set注入可以在对象创建后注入如果在只考虑单线程的情况下我们可以用一个对象来应对各种扩展逻辑的变化当然这不太符合单一职责原则谨慎使用为妙 下面我们讲讲适配器模式本质适配器解决是接口不兼容问题将一个接口转换成客户希望的另一个接口使接口不兼容的那些类可以一起工作其别名为包装器Wrapper。适配器模式既可以作为类结构型模式也可以作为对象结构型模式。 适配器模式也分为类适配器模式类适配器模式可以适配多个被适配者类但是被适配者类的方法必须是可访问的本质就是通过继承的方式实现对象适配器模式对象适配器模式可以适配多个被适配者类且被适配者类的方法可以是私有的而且适配器类可以与被适配者类独立变化本质就是通过组合的方式实现和接口适配器模式接口适配器模式可以适配多个目标接口因为适配器类是抽象类可以定义多个抽象方法和默认实现。双向适配器模式其实就是在适配器中组合双向适配的接口然后在具体实现中完成方法调用的转换单接口/缺省适配器模式(当不需要实现一个接口所提供的所有方法时可先设计一个抽象类实现该接口并为接口中每个方法提供一个默认实现空方法那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求。它适用于不想使用一个接口中的所有方法的情况)。没啥好讲的适配器模式可能是结构型模式中最好理解的设计模式了。如过场景可以在组合和继承的实现方式中选择一种优先选组合方式来实现适配器-组合/聚合优先原则(注意这里的组合可不是组合模式) 后面我们谈谈组合模式组合模式本质是将树形结构的一些需要递归遍历的操作通过结构的设计省去调用递归函数的逻辑组合模式的关键是定义了一个抽象构件类它既可以代表叶子又可以代表容器。客户端针对该抽象构件类进行编程无须知道它到底表示的是叶子还是容器可以对其进行统一处理。同时容器对象与抽象构件类之间还建立一个聚合关联关系在容器对象中既可以包含叶子也可以包含容器以此实现递归组合形成一个树形结构。 组合模式又分透明组合模式如图抽象构件中声明了所有用于管理成员对象的方法
和安全组合模式如图
抽象构件中只声明叶子节点和树枝节点的共有方法因为叶子构件和容器构件具有不同的方法且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义客户端不能完全针对抽象编程必须有区别地对待叶子构件和容器构件
一般情况下这里最佳的选择方案应该是在透明组合模式的基础上对叶子节点实现类的管理成员对象的方法做一些安全校验与异常处理与提示。 再后面我们谈谈享元模式定义运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象而这些对象都很相似状态变化很小可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象因此它又称为轻量级模式是一种对象结构型模式。享元模式本质就是通过共享技术实现相同或相似对象的重用从而降低程序运行时对jvm内存的消耗,
实现享元模式关键在于区分内部状态与外部状态不同于桥接模式的抽象与实现的分离享元模式通过将对象的内部状态共享在缓存中外部状态由创建时或创建后指定
享元模式类图 复合享元模式类图 最后讲讲外观模式外部与一个子系统的通信通过一个统一的外观角色进行为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口这个接口使得子系统更加容易使用。外观模式又称为门面模式它是一种对象结构型模式。
在软件开发中有时候为了完成一项较为复杂的功能一个类需要和多个其他业务类交互而这些需要交互的业务类经常会作为一个完整的整体出现由于涉及的类比较多导致使用时代码较为复杂。此时特别需要一个类似服务员一样的角色由它来负责和多个业务类进行交互而使用这些业务类的类只需和该类交互即可。外观模式通过引入一个新的外观类来实现该功能。外观类多个业务类的调用提供了一个统一的入口简化了类与类之间的交互。