怎么做英文网站,网站建设基本费用,东莞合一网络科技有限公司,wordpress如何修改首页模板文件设计模式的分类
总体来说设计模式分为三大类#xff1a;
创建型模式#xff0c;共五种#xff1a;工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式#xff0c;共七种#xff1a;适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合…设计模式的分类
总体来说设计模式分为三大类
创建型模式共五种工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式共七种适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式共十一种策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
一、创建模式5种
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
1 工厂模式
1.1 简单工厂模式
定义定义了一个创建对象的类由这个类来封装实例化对象的行为。 简单工厂存在的问题与解决方法 简单工厂模式有一个问题就是类的创建依赖工厂类也就是说如果想要拓展程序必须对工厂类进行修改这违背了开闭原则所以从设计角度考虑有一定的问题如何解决我们可以定义一个创建对象的抽象方法并创建多个不同的工厂类实现该抽象方法这样一旦需要增加新的功能直接增加新的工厂类就可以了不需要修改之前的代码。这种方法也就是我们接下来要说的工厂方法模式。
1.2 工厂方法模式
定义定义了一个创建对象的抽象方法由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。 工厂方法存在的问题与解决方法客户端需要创建类的具体的实例。简单来说就是用户要订纽约工厂的披萨他必须去纽约工厂想订伦敦工厂的披萨必须去伦敦工厂。 当伦敦工厂和纽约工厂发生变化了用户也要跟着变化这无疑就增加了用户的操作复杂性。为了解决这一问题我们可以把工厂类抽象为接口用户只需要去找默认的工厂提出自己的需求传入参数便能得到自己想要产品而不用根据产品去寻找不同的工厂方便用户操作。这也就是我们接下来要说的抽象工厂模式。
1.3 抽象工厂模式
定义定义了一个接口用于创建相关或有依赖关系的对象族而无需明确指定具体类。 解决了工厂方法模式的问题在抽象工厂中只需要传入参数就可以实例化对象。
1.4 工厂模式适用的场合
大量的产品需要创建并且这些产品具有共同的接口 。
简单工厂模式就是建立一个实例化对象的类在该类中对多个对象实例化。工厂方法模式是定义了一个创建对象的抽象方法由子类决定要实例化的类。这样做的好处是再有新的类型的对象需要实例化只要增加子类即可。抽象工厂模式定义了一个接口用于创建对象族而无需明确指定具体类。抽象工厂也是把对象的实例化交给了子类即支持拓展。同时提供给客户端接口避免了用户直接操作子类工厂。
2 单例模式
定义确保一个类最多只有一个实例并提供一个全局访问点
单例模式可以分为两种预加载和懒加载
2.1 预加载
顾名思义就是预先加载。再进一步解释就是还没有使用该单例对象但是该单例对象就已经被加载到内存了。 很明显没有使用该单例对象该对象就被加载到了内存会造成内存的浪费。
2.2 懒加载
为了避免内存的浪费我们可以采用懒加载即用到该单例对象的时候再创建。
2.3 单例模式和线程安全
1预加载只有一条语句return instance,这显然可以保证线程安全。但是我们知道预加载会造成内存的浪费。
2懒加载不浪费内存但是无法保证线程的安全。首先if判断以及其内存执行代码是非原子性的。其次new Singleton()无法保证执行的顺序性。
不满足原子性或者顺序性线程肯定是不安全的这是基本的常识不再赘述。我主要讲一下为什么new Singleton()无法保证顺序性
2.4 保证懒加载的线程安全
我们首先想到的就是使用synchronized关键字。synchronized加载getInstace()函数上确实保证了线程的安全。但是如果要经常的调用getInstance()方法不管有没有初始化实例都会唤醒和阻塞线程。为了避免线程的上下文切换消耗大量时间如果对象已经实例化了我们没有必要再使用synchronized加锁直接返回对象。
3 生成器模式
定义封装一个复杂对象构造过程并允许按步骤构造。
定义解释 我们可以将生成器模式理解为假设我们有一个对象需要建立这个对象是由多个组件Component组合而成每个组件的建立都比较复杂但运用组件来建立所需的对象非常简单所以我们就可以将构建复杂组件的步骤与运用组件构建对象分离使用builder模式可以建立。
3.1 模式的结构和代码示例
生成器模式结构中包括四种角色
1产品(Product)具体生产器要构造的复杂对象
2抽象生成器(Bulider)抽象生成器是一个接口该接口除了为创建一个Product对象的各个组件定义了若干个方法之外还要定义返回Product对象的方法定义构造步骤
3具体生产器(ConcreteBuilder)实现Builder接口的类具体生成器将实现Builder接口所定义的方法生产各个组件
4指挥者(Director)指挥者是一个类该类需要含有Builder接口声明的变量。指挥者的职责是负责向用户提供具体生成器即指挥者将请求具体生成器类来构造用户所需要的Product对象如果所请求的具体生成器成功地构造出Product对象指挥者就可以让该具体生产器返回所构造的Product对象。按照步骤组装部件并返回Product
3.2 生成器模式的优缺点
优点
将一个对象分解为各个组件 将对象组件的构造封装起来 可以控制整个对象的生成过程 缺点
对不同类型的对象需要实现不同的具体构造器的类这可能回答大大增加类的数量
3.3 生成器模式与工厂模式的不同
生成器模式构建对象的时候对象通常构建的过程中需要多个步骤就像我们例子中的先有主机再有显示屏再有鼠标等等生成器模式的作用就是将这些复杂的构建过程封装起来。工厂模式构建对象的时候通常就只有一个步骤调用一个工厂方法就可以生成一个对象。
4 原型模式
定义通过复制现有实例来创建新的实例无需知道相应类的信息。
简单地理解其实就是当需要创建一个指定的对象时我们刚好有一个这样的对象但是又不能直接使用我会clone一个一毛一样的新对象来使用基本上这就是原型模式。关键字Clone。
4.1 深拷贝和浅拷贝
浅复制将一个对象复制后基本数据类型的变量都会重新创建而引用类型指向的还是原对象所指向的。
深复制将一个对象复制后不论是基本数据类型还有引用类型都是重新创建的。简单来说就是深复制进行了完全彻底的复制而浅复制不彻底。clone明显是深复制clone出来的对象是是不能去影响原型对象的
原型模式的本质就是clone可以解决构建复杂对象的资源消耗问题能再某些场景中提升构建对象的效率还有一个重要的用途就是保护性拷贝可以通过返回一个拷贝对象的形式实现只读的限制。
二、结构模式7种
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
5 适配器模式
定义 适配器模式将某个类的接口转换成客户端期望的另一个接口表示目的是消除由于接口不匹配所造成的类的兼容性问题。
主要分为三类类的适配器模式、对象的适配器模式、接口的适配器模式。
5.1 类适配器模式
通过多重继承目标接口和被适配者类方式来实现适配
5.2 对象适配器模式
对象适配器和类适配器使用了不同的方法实现适配对象适配器使用组合类适配器使用继承。
5.3 接口适配器模式
当不需要全部实现接口提供的方法时可先设计一个抽象类实现接口并为该接口中每个方法提供一个默认实现空方法那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求它适用于一个接口不想使用其所有的方法的情况。
类适配器模式当希望将一个类转换成满足另一个新接口的类时可以使用类的适配器模式创建一个新类继承原有的类实现新的接口即可。
对象适配器模式当希望将一个对象转换成满足另一个新接口的对象时可以创建一个Wrapper类持有原类的一个实例在Wrapper类的方法中调用实例的方法就行。
接口适配器模式当不希望实现一个接口中所有的方法时可以创建一个抽象类Wrapper实现所有方法我们写别的类的时候继承抽象类即可。
6 装饰者模式
定义动态的将新功能附加到对象上。在对象功能扩展方面它比继承更有弹性。
6.1 装饰者模式结构图与代码示例
1.Component被装饰对象的基类
定义一个对象接口可以给这些对象动态地添加职责。
2.ConcreteComponent具体被装饰对象
定义一个对象可以给这个对象添加一些职责。
3.Decorator装饰者抽象类
维持一个指向Component实例的引用并定义一个与Component接口一致的接口。
4.ConcreteDecorator具体装饰者
具体的装饰对象给内部持有的具体被装饰对象增加具体的职责。
被装饰对象和修饰者继承自同一个超类
装饰者和被装饰者之间必须是一样的类型,也就是要有共同的超类。在这里应用继承并不是实现方法的复制,而是实现类型的匹配。因为装饰者和被装饰者是同一个类型,因此装饰者可以取代被装饰者,这样就使被装饰者拥有了装饰者独有的行为。根据装饰者模式的理念,我们可以在任何时候,实现新的装饰者增加新的行为。如果是用继承,每当需要增加新的行为时,就要修改原程序了。
7 代理模式
定义代理模式给某一个对象提供一个代理对象并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
7.1 为什么要用代理模式
中介隔离作用在某些情况下一个客户类不想或者不能直接引用一个委托对象而代理类对象可以在客户类和委托对象之间起到中介的作用其特征是代理类和委托类实现相同的接口。
开闭原则增加功能代理类除了是客户类和委托类的中介之外我们还可以通过给代理类增加额外的功能来扩展委托类的功能这样做我们只需要修改代理类而不需要再修改委托类符合代码设计的开闭原则。代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类以及事后对返回结果的处理等。代理类本身并不真正实现服务而是同过调用委托类的相关方法来提供特定的服务。真正的业务功能还是由委托类来实现但是可以在业务功能执行的前后加入一些公共的服务。例如我们想给项目加入缓存、日志这些功能我们就可以使用代理类来完成而没必要打开已经封装好的委托类。
代理模式分为三类
1. 静态代理
优点可以做到在符合开闭原则的情况下对目标对象进行功能扩展。缺点 代理对象与目标对象要实现相同的接口我们得为每一个服务都得创建代理类工作量太大不易管理。同时接口一旦发生改变代理类也得相应修改。2. 动态代理
动态代理有以下特点:1.代理对象,不需要实现接口2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)代理类不用再实现接口了。但是要求被代理对象必须有接口。
虽然相对于静态代理动态代理大大减少了我们的开发任务同时减少了对业务接口的依赖降低了耦合度。但是还是有一点点小小的遗憾之处那就是它始终无法摆脱仅支持interface代理的桎梏我们要使用被代理的对象的接口因为它的设计注定了这个遗憾。3. CGLIB代理
CGLIB 原理动态生成一个要代理类的子类子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。CGLIB 底层使用字节码处理框架ASM来转换字节码并生成新的类。不鼓励直接使用ASM因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。CGLIB缺点对于final方法无法进行代理。8 外观模式
定义 隐藏了系统的复杂性并向客户端提供了一个可以访问系统的接口。 优点
- 松散耦合
使得客户端和子系统之间解耦让子系统内部的模块功能更容易扩展和维护
- 简单易用
客户端根本不需要知道子系统内部的实现或者根本不需要知道子系统内部的构成它只需要跟Facade类交互即可。
- 更好的划分访问层次
有些方法是对系统外的有些方法是系统内部相互交互的使用的。子系统把那些暴露给外部的功能集中到门面中这样就可以实现客户端的使用很好的隐藏了子系统内部的细节。
9 桥接模式
定义 将抽象部分与它的实现部分分离使它们都可以独立地变化。
优点
(1)在很多情况下桥接模式可以取代多层继承方案多层继承方案违背了“单一职责原则”复用性较差且类的个数非常多桥接模式是比多层继承方案更好的解决方法它极大减少了子类的个数。
(2)桥接模式提高了系统的可扩展性在两个变化维度中任意扩展一个维度都不需要修改原有系统符合“开闭原则”。
缺点
桥接模式的使用会增加系统的理解与设计难度由于关联关系建立在抽象层要求开发者一开始就针对抽象层进行设计与编程