愿景:"让编程不再难学,让技术与生活更加有趣"
更多架构课程请访问 xdclass.net
目录
第1集 接口之间的桥梁-适配器设计模式你知道多少
简介:讲解Adapeter设计模式和应用场景
-
适配器模式(Adapter Pattern)
-
见名知意,是作为两个不兼容的接口之间的桥梁,属于结构型模式
-
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
-
常见的几类适配器
-
类的适配器模式
-
想将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可
-
-
对象的适配器模式
- 想将一个对象转换成满足另一个新接口的对象时,可以创建一个适配器类,持有原类的一个实例,在适配器类的方法中,调用实例的方法就行
-
接口的适配器模式
- 不想实现一个接口中所有的方法时,可以创建一个Adapter,实现所有方法,在写别的类的时候,继承Adapter类即
-
-
-
应用场景
- 电脑需要读取内存卡的数据,读卡器就是适配器
- 日常使用的转换头,如电源转换头,电压转换头
- 系统需要使用现有的类,而这些类的接口不符合系统的需要
- JDK中InputStreamReader就是适配器
- JDBC就是我们用的最多的适配器模式
JDBC给出一个客户端通用的抽象接口,每一个具体数据库厂商 如 SQL Server、Oracle、MySQL等,就会开发JDBC驱动,就是一个介于JDBC接口和数据库引擎接口之间的适配器软件
第2集 提高开发效率 接口适配器在日常开发里面的应用
简介:接口的适配器案例实战
-
设计模式的疑惑
-
会感觉到好像是理解了模式的功能,但是一到真实的系统开发中,就不知道如何使用这个模式了
-
前面每个案例都有讲实际的编码操作,大家一定要充分领悟
-
-
接口适配器
有些接口中有多个抽象方法,当我们写该接口的实现类时,必须实现该接口的所有方法,这明显有时比较浪费,因为并不是所有的方法都是我们需要的,有时只需要实现部分接口就可以了
- 编码实战
第3集 生产环境接口-需要兼容新的业务怎么办?
简介:适配器案例实战,生产环境得的接口需要兼容新的业务
- 需求背景
小滴课堂里面有个电商支付项目,里面有个登录功能,已经线上运行了
客户端A 调用生产环境的登录接口B,且线上稳定运行了好几年。
某天,公司接到收购了别的公司的项目,需要把这套系统部署在起来,且收购的项目也有对应的客户端C,但是两个客户端和服务端的协议不一样
需求:收购的项目客户端C,需要做公司原来的项目用户数据打通,连接公司的服务端登录接口B,你能想到几个解决方案?
1、修改就项目B的登录接口,兼容C客户端协议(可能影响线上接口,不稳定)
2、新增全新的登录接口F,采用C客户端协议(和旧的业务逻辑会重复)
3、新增一个转换协议接口,客户端C调用旧的B接口之前,使用转换接口转换下协议(适配器模式,推荐这个方式)
-
总结
-
在使用一些旧系统或者是类库时,经常会出现接口不兼容的问题,适配器模式在解决这类问题具有优势
-
学习设计模式一定不要局限代码层面,要从软件系统整体去考虑,而不是为了使用设计模式,而去使用设计模式
-
-
优点
- 可以让任何两个没有关联的类一起运行,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
- 增加灵活度, 提高复用性,适配器类可以在多个系统使用,符合开闭原则
-
缺点
- 整体类的调用链路增加,本来A可以直接调用C,使用适配器后 是A调用B,B再调用C
第4集 适配器设计模式-类的适配器
简介:适配器案例实战,类的适配器
-
类的适配器模式
- 想将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可
/**
* 小滴课堂,愿景:让技术不再难学 xdclass.net
*
* @Description 老的类,里面有1个方法
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信: xdclass6
* @Version 1.0
**/
public class OldModule {
public void methodA(){
System.out.println("OldModule methodA");
}
}
public interface TargetModule {
/**
* 和需要适配的类方法名一样
*/
void methodA();
/**
* 新的方法,如果有多个新的方法直接编写就行
*/
void methodB();
void methodC();
}
public class Adapter extends OldModule implements TargetModule {
/**
* 新的方法,和老的类方法不一样
*/
@Override
public void methodB() {
System.out.println("Adapter methodB");
}
/**
* 新的方法,和老的类方法不一样
*/
@Override
public void methodC() {
System.out.println("Adapter methodC");
}
}
public static void main(String[] args) {
TargetModule targetModule = new Adapter();
targetModule.methodA();
targetModule.methodB();
targetModule.methodC();
}
第5集 设计模式疑惑指南-桥接设计模式
简介:学设计模式的疑惑,桥接设计模式的介绍
-
打个鸡血
-
牛逼的工程师,在日常开发,明明用了某种设计模式了,但他还没意识到是哪种模式,只知道这样做是最合适的,这种就是已经把设计模式融会贯通了。
- 而那种刚学了一点设计模式就到处想用,以及把精力浪费在区分各个设计模式上的人,未来就陷入死循环里面。
-
桥接设计模式
- 适配器模式类似,包括以后经常会遇到意思接近一样的设计模式,因为大神往往就是多个模式混用,且根据不同的场景进行搭配,桥接设计模式也是结构型模式
- 将抽象部分与实现部分分离,使它们都可以独立的变化
- 通俗来说,是通过组合来桥接其它的行为/维度
-
应用场景
- 系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性
- 不想使用继承导致系统类的个数急剧增加的系统
- 有时候一个类,可能会拥有多个变化维度,比如啤酒,有不同的容量和品牌,可以使用继承组合的方式进行开发,假如维度很多,就容易出现类的膨胀,使用桥接模式就可以解决这个问题,且解耦
- 业务背景
我们需要构建一个手机类,我们知道手机有很多品牌,苹果、华为等,从另外一个颜色维度,又有多种颜色,红、黄、蓝等,
那如果描述这些类的话,传统方式就直接通过继承,就需要特别多的类,品牌2,颜色3,就是6个类了,如果后续再增加品牌就更多了,类数目将会激增,即所谓的类爆炸
使用桥接模式就可以解决这个问题,且灵活度大大提高
第6集 桥接设计模式案例实战
简介:桥接设计模式的案例实战
- 编码实战
/**
* 小滴课堂,愿景:让技术不再难学
*
* @Description 抽象角色 手机
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群
* @Version 1.0
**/
public abstract class Phone {
/**
* 通过组合的方式来桥接其他行为
*/
protected Color color;
public void setColor(Color color) {
this.color = color;
}
/**
* 手机的方法
*/
abstract public void run();
}
//颜色维度
public interface Color {
void useColor();
}
//具体颜色
public class BlueColor implements Color {
@Override
public void useColor() {
System.out.println("蓝色");
}
}
/**
* 小滴课堂,愿景:让技术不再难学
*
* @Description 手机的实例化
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群
* @Version 1.0
**/
public class HWPhone extends Phone {
public HWPhone(Color color){
super.setColor(color);
}
@Override
public void run() {
color.useColor();
System.out.println("华为手机");
}
}
//使用,把组合的形式
public static void main(String[] args) {
HWPhone blueHwPhone = new HWPhone(new BlueColor());
blueHwPhone.run();
HWPhone redHwPhone = new HWPhone(new RedColor());
redHwPhone.run();
ApplePhone applePhone = new ApplePhone(new RedColor());
applePhone.run();
}
-
优点
- 抽象和实现的分离。
- 优秀的扩展能力,符合开闭原则
-
缺点
- 增加系统的理解与设计难度
- 使用聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程,比如抽象类汽车,里面聚合了颜色类,有点像对象适配器
-
总结和对比
-
按GOF的说法,桥接模式和适配器模式用于设计的不同阶段,
- 桥接模式用于设计的前期,精细化的设计,让系统更加灵活
- 适配器模式用于设计完成之后,发现类、接口之间无法一起工作,需要进行填坑
-
适配器模式经常用在第三方API协同工作的场合,在功能集成需求越来越多的今天,这种模式的使用频度越来越高,包括有些同学听过 外观设计模式 ,这个也是某些场景和适配器模式一样
-
第7集 将对象组合成树形结构的模式-组合设计模式讲解
简介:介绍组合设计模式
-
组合设计模式
- 又叫部分整体模式,将对象组合成树形结构以表示“部分-整体”的层次结构,可以更好的实现管理操作
- 组合模式使得用户可以使用一致的方法操作单个对象和组合对象
- 部分-整体对象的基本操作多数是一样的,但是应该还会有不一样的地方
- 核心:组合模式可以使用一棵树来表示
-
应用场景
- 银行总行,总行有前台、后勤、网络部门等,辖区下还有地方分行,也有前台、后勤、网络部门,最小的分行就没有子分行了
- 公司也是,总公司下有子公司,每个公司大部分的部门都类似
- 文件夹和文件,都有增加、删除等api,也有层级管理关系
- 当想表达对象的部分-整体的层次结构
- 当我们的要处理的对象可以生成一颗树形结构,我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子
-
角色
-
组合部件(Component):它是一个抽象接口,表示树根,例子:总行
-
合成部件(Composite):和组合部件类似,也有自己的子节点,例子:总行下的分行
-
叶子(Leaf):在组合中表示子节点对象,注意是没有子节点,例子:最小地方的分行
-
第8集 组合设计模式实战-文件展示-树叶子节点
简介:组合设计模式文件展示-树叶子节点
- 编码实战
/**
* 小滴课堂,愿景:让技术不再难学 https://xdclass.net
*
* @Description 根节点,抽象类,通用的属性和方法
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信 xdclass6
* @Version 1.0
**/
public abstract class Root {
private String name;
public Root(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void addFile(Root root);
public abstract void removeFile(Root root);
public abstract void display(int depth);
}
/**
* 小滴课堂,愿景:让技术不再难学 xdclass.net
*
* @Description 具体的文件夹,里面可以添加子文件夹或者文件
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群 微信 xdclass6
* @Version 1.0
**/
public class Folder extends Root {
List<Root> folders = new ArrayList<>();
public Folder(String name){
super(name);
}
public List<Root> getFolders() {
return folders;
}
public void setFolders(List<Root> folders) {
this.folders = folders;
}
@Override
public void addFile(Root root) {
folders.add(root);
}
@Override
public void removeFile(Root root) {
folders.remove(root);
}
@Override
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<depth;i++){
sb.append("-");
}
//打印横线和当前文件名
System.out.println(sb.toString()+this.getName());
for(Root r : folders){
//每个下级,横线多2个
r.display(depth+2);
}
}
}
/**
* 小滴课堂,愿景:让技术不再难学 xdclass.net
*
* @Description 这个类是没有节点,不用存储其他子类数组,所以是叶子节点
* @Author 二当家小D
* @Remark 有问题直接联系我,源码-笔记-技术交流群,微信 xdclass6
* @Version 1.0
**/
public class File extends Root{
public File(String name){
super(name);
}
@Override
public void addFile(Root root) {
}
@Override
public void removeFile(Root root) {
}
@Override
public void display(int depth) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<depth;i++){
sb.append("-");
}
//打印横线和当前文件名
System.out.println(sb.toString()+this.getName());
}
}
//使用
public static void main(String[] args) {
//创造根文件夹
Root root1 = new Folder("C://");
//建立子文件
Root desktop = new Folder("桌面");
Root myComputer = new Folder("我的电脑");
//建立子文件
Root javaFile = new File("HelloWorld.java");
//建立文件夹关系
root1.addFile(desktop);
root1.addFile(myComputer);
//建立文件关系
myComputer.addFile(javaFile);
//从0级开始展示,每下一级,多2条横线
root1.display(0);
//另外一个根
Root root2 = new Folder("D://");
root2.display(0);
}
-
缺点
- 客户端需要花更多时间理清类之间的层次关系
-
优点
- 客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题
- 方便创建出复杂的层次结构