目录
1、适配器模式
1.1 什么是适配器模式
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 做法是将类自己的接口包裹在一个已存在的类中。
适配器模式分为;两种适配器,分别是类适配器模式和对象适配器模式
1.2 类适配器模式
实例:手机充电需要将220V的交流电转化为手机锂电池需要的5V直流电。使用电源适配器,将 AC220v ——> DC5V。
类图:
实现方式:让Adapter继承Adaptee类,然后再实现Target接口,来实现适配器功能。
- Adaptee:适配者类,它是需要被访问的、需要被适配的组件. AC220V
- Target:目标接口,当前系统业务所使用的接口,可以是抽象类或接口. DC5V
- Adapter:适配器类,通过继承和实现目标接口,让客户端按照目标接口的方法访问适配者
- Client:客户端,适配器的使用者
1.2.1 代码实现
源角色(Adaptee):现在需要适配的接口。
public class AC220 { /** * 输出220V交流电 * * @return */ public int output220V() { int output = 220; return output; } }
目标角色(Target):这就是所期待得到的接口。
public interface DC5 { /** * 输出5V直流电(期待得到的接口) * * @return */ int output5V(); }
类适配器:适配器类是本模式的核心。适配器把源接口转换成目标接口。
public class PowerAdapter extends AC220 implements DC5 { /** * 输出5V直流电 * * @return */ @Override public int output5V() { int output = output220V(); return (output / 44); } }
测试类适配器
public class TestClassAdapter { public static void main(String[] args) { DC5 dc5 = new PowerAdapter(); System.out.println("输出电流:" + dc5.output5V() + "V"); } }
1.2.2 优缺点
优点:由于Adapter继承了Adaptee类,所以它可以根据需求重写Adaptee类的方法,使得Adapter的灵活性增强了。
缺点:因为java单继承的缘故,Target类==必须是接口==,以便于Adapter去继承Adaptee并实现Target,完成适配的功能,但这样就导致了Adapter里暴露了Adaptee类的方法,使用起来的成本就增加了。
1.3 对象适配器模式
实例:手机充电需要将220V的交流电转化为手机锂电池需要的5V直流电。使用电源适配器,将 AC220v ——> DC5V。
类图:
实现方式:让Adapter持有Adaptee类的实例,然后再实现Target接口,以这种持有对象的方式来实现适配器功能。
- Adaptee:适配者类,它是需要被访问的、需要被适配的组件
- Target:目标接口,当前系统业务所使用的接口,可以是抽象类或接口
- Adapter:适配器类,通过聚合和实现目标接口,让客户端按照目标接口的方法访问适配者
- Client:客户端,适配器的使用者
1.3.1 代码实现
源角色(Adaptee):现在需要适配的接口。
public class AC220 { /** * 输出220V交流电 * * @return */ public int output220V() { int output = 220; return output; } }
目标角色(Target):这就是所期待得到的接口。
public interface DC5 { /** * 输出5V直流电(期待得到的接口) * * @return */ int output5V(); }
对象适配器
public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } /** * 输出5V直流电 * * @return */ @Override public int output5V() { int output = this.ac220.output220V(); return (output / 44); } }
测试对象适配器
public class TestObjectAdapter { public static void main(String[] args) { AC220 ac220 = new AC220(); PowerAdapter powerAdapter = new PowerAdapter(ac220); System.out.println("输出电流:" + powerAdapter.output5V() + "V"); } }
1.3.2 优缺点
对象适配器模式的优点主要包括:
- 解耦:将目标类和适配者类解耦,增加了类的透明性和复用性。这意味着适配者类的实现细节对客户端类是透明的,提高了适配者的复用性。
- 灵活性和扩展性:系统的灵活性和扩展性都非常好,符合“开闭原则”。这意味着更换适配器或增加新的适配器都非常方便,无需修改现有的代码。
- 低耦合度:与类适配器模式相比,对象适配器中适配者类和适配器类的耦合度要更低,提供了更灵活的适配方式。
对象适配器模式的缺点主要包括:
- 难以置换适配者类的方法:由于对象适配器模式的耦合度较低,因此在某些情况下,可能难以直接置换适配者类的方法,这可能会限制某些功能的实现。
- 不能同时适配多个适配者类:在某些编程语言中,对象适配器模式可能无法同时适配多个适配者类,这可能会限制其在需要处理多种不同接口情况下的应用。
综上所述,对象适配器模式通过降低适配者类和适配器类的耦合度,提供了更高的灵活性和扩展性,但同时也面临着难以直接置换适配者类方法和无法同时适配多个适配者类的挑战。
2、观察者模式
2.1 什么是观察者模式
观察者(Observer)模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式、发布-订阅模式、模型-视图模式)是软件设计模式的一种。是指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。它是对象行为型模式。
2.2 观察者模式的结构
观察者模式的主要角色如下:
抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
2.3 案例
2.3.1 需求
做一个案例,公众号推送消息,关注这个公众号的客户可以接收到消息。
2.3.2 如何实现?
观察者模式首先有一个被观察类,这个类中有一个 ArrayList 存放观察者们。除此以外还应有类状态和设置和获取状态的方法,状态改变时通知所有观察者,观察者类可以有个抽象类,所有的观察者类继承这个抽象类,观察者类有它要观察的对象。
2.3.3 案例分析
观察者模式分为四个角色:
1.抽象被观察者角色
抽象出一个公众号接口/抽象类
公共的方法:
关注方法
取关方法
设置推送消息方法
群发方法2.被观察者角色
有一个具体的公众号,实现/继承 抽象被观察者3.抽象观察者角色
抽象出一个客户 接口/抽象类
公共方法:
接收公众号推送的消息
4.观察者角色
具体用户 实现/继承 抽象观察者
2.3.4 代码实现
抽象观察者角色
package demo02; /** * @program: java高级-设计模式 * @description: * @author: Hanshy123 * @create: 2024-07-12 10:57 **/ public interface UserInterface { /** * 接受公众号发生的消息 * @param msg */ public void getMsg(String msg); }
观察者角色
package demo02; /** * @program: java高级-设计模式 * @description: * @author: Hanshy123 * @create: 2024-07-12 10:58 **/ public class User implements UserInterface { private String name; public User(String name) { this.name = name; } public void getMsg(String msg) { System.out.println(name+"接受到公众号发送的消息:"+msg); } }
抽象公众号
package demo02; /** * @program: java高级-设计模式 * @description: * @author: Hanshy123 * @create: 2024-07-12 11:01 **/ public interface PublicHaoInterface { public void add(UserInterface userInterface); public void remove(UserInterface userInterface); public void setMsg(String msg); public void qunfa(); }
具体公共号
package demo02; import java.util.ArrayList; import java.util.List; /** * @program: java高级-设计模式 * @description: * @author: Hanshy123 * @create: 2024-07-12 11:02 **/ public class AAAPublicHao implements PublicHaoInterce { List<UserInterface> list=new ArrayList<UserInterface>(); //设置消息 private String msg; public void add(UserInterface userInterface) { list.add(userInterface); } public void remove(UserInterface userInterface) { list.remove(userInterface); } public void setMsg(String msg) { this.msg=msg; } public void qunfa() { for(UserInterface userInterface:list){ userInterface.getMsg(msg); } } }
2.3.5 优缺点
观察者模式是一种对象行为型模式,其主要优点如下:
降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 目标与观察者之间建立了一套触发机制。
它的主要缺点如下:
目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。