适配器模式
定义:适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作
角色:
1.目标(Target)角色
2.源(Adapee)角色
3.适配器(Adapter)角色
1.类适配器,通过适配器继承自源角色之后实现目标角色即可拥有目标角色的方法
(不推荐使用,因为继承有很大的局限性,不能使用adaptee子类的方法)
场景:连接显示屏是HDMI线,但是电脑上只有type-c接口,这时我们可以使用一个转换器,这样电脑屏幕就可以连接到显示屏了
public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1(){}
}
public class Adapter extends Adaptee implements Target {
/**
* 由于源类Adaptee没有方法sampleOperation2() * 因此适配器补充上这个方法
*/
@Override
public void sampleOperation2() {
//写相关的代码 }
}
2.对象适配器(推荐使用)
public interface Target {
/**
* 这是源类Adaptee也有的方法
*/
public void sampleOperation1();
/**
* 这是源类Adapteee没有的方法
*/
public void sampleOperation2();
}
public class Adaptee {
public void sampleOperation1(){}
}
public class Adapter {
private Adaptee adaptee;
public Adapter(Adaptee adaptee){
this.adaptee = adaptee;
}
/**
* 源类Adaptee有方法sampleOperation1 * 因此适配器类直接委派即可
*/
public void sampleOperation1(){
this.adaptee.sampleOperation1();
}
/**
* 源类Adaptee没有方法sampleOperation2 * 因此由适配器类需要补充此方法
*/
public void sampleOperation2(){
//写相关的代码
}
}
优点:
更好的复用性,利用现在的接口接口即可完成需求,不用新建
更好的扩展性:可以实现适配器功能的时候加入自己的方法
缺点:容易让系统变得复杂,明明是调用A接口,之后适配器调用的是B接口
外观模式
定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对 象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接 口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种 对象结构型模式。
结构图:
截屏2020-08-23 下午8.40.47.png
场景:把外观模式想象为一个前台,有人来公司时,需要申请访客码、填写资料、预约这些流程,如果用访客来做这项工作的话,访客就会访问做几件事,还不一定能搞定,这时安排一个前台,访客只需要跟前台说明来意,前台就能帮他完成,用户都不用知晓这些流程
代码实现:
public class ModuleA {
//示意方法
public void testA(){
System.out.println("调用ModuleA中的testA方法");
}
}
public class ModuleB {
//示意方法
public void testB(){
System.out.println("调用ModuleB中的testB方法");
}
}
public class ModuleC {
//示意方法
public void testC(){
System.out.println("调用ModuleC中的testC方法");
}
}
//外观角色类,相当于前台
public class Facade {
//示意方法,满足客户端需要的功能
public void test(){
ModuleA a = new ModuleA();
a.testA();
ModuleB b = new ModuleB();
b.testB();
ModuleC c = new ModuleC();
c.testC(); }
}
//客户端,相当于访客
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.test(); }
}
优点:降低了客户端和子系统的耦合关系,让子系统内部的模块能更容易扩展,减少内部的暴露
装饰者模式
定义:装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象 的功能,是继承关系的一个替代方案。装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提供了比继承更 有弹性的替代方案。
元素:抽象构件(Component)、具体构件(ConcreteComponent)、装饰(Decorator)、具体装饰(ConcreteDecorator)
场景:对Java IO流进行装饰
代码实现:
public interface Component {
public void sampleOperation();
}
public class ConcreteComponent implements Component {
@Override
public void sampleOperation() {
// 写相关的业务代码 }
}
public class Decorator implements Component{
private Component component;
public Decorator(Component component){
this.component = component;
}
@Override
public void sampleOperation() {
// 委派给构件
component.sampleOperation();
}
}
public class ConcreteDecoratorA extends Decorator {
public ConcreteDecoratorA(Component component) {
super(component);
}
@Override
public void sampleOperation() {
// 写相关的业务代码
super.sampleOperation();
// 写相关的业务代码
}
}
优点:装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以 提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或 者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行 前就决定了。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创 造出很多不同行为的组合。
缺点:由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类, 当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关 系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相 像。
在Java中的应用
public class IOTest {
public static void main(String[] args) throws IOException { // 流式读取文件
DataInputStream dis = null;
try{
dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("test.txt")) );
//读取文件内容
byte[] bs = new byte[dis.available()]; dis.read(bs);
String content = new String(bs);
System.out.println(content);
}finally{
dis.close();
}
}
}
代理模式
定义:给摸一个对象提供一个代理,并由代理对象控制对原对象的引用
角色:Subject(抽象代理类,可以是接口)、Proxy(代理对象)、RealSubject(真实主题角色)
场景:
买火车票,购买火车票是一个主题类,真实的主题类时火车站,代理模式是飞猪APP,我们购买火车票可以直接通过飞猪购买
代码实现
public abstract class AbstractObject { //操作
public abstract void operation();
}
//真实主题类
public class RealObject extends AbstractObject {
@Override
public void operation() { //一些操作
System.out.println("一些操作"); }
}
//代理类
public class ProxyObject extends AbstractObject{
RealObject realObject = new RealObject();
@Override
public void operation() {
//调用目标对象之前可以做相关操作
System.out.println("before");
realObject.operation();
//调用目标对象之后可以做相关操作
System.out.println("after");
}
}
//客户端调用
public class Client {
public static void main(String[] args) {
AbstractObject obj = new ProxyObject();
obj.operation(); }
}
}
网友评论