目录

1.构建型设计模型

工厂模式:

抽象工厂模式

2.单例模式

饿汉式:

懒汉式:

3.建造型模式

4.原型模式

2.结构型模式

适配器模式

桥接模式

组合模式

装饰模式

外观模式

享元模式

代理模式

静态代理:

动态代理


1.构建型设计模型

工厂模式:

类比于我们想要产品,那么产品从工厂里获取,我们不需要知道怎么生产的,只要工厂给我们就可以了

public class FruitFactory {public Fruit create(String type) {switch (type) {case "苹果":AppleSeed appleSeed = new AppleSeed();Sunlight sunlight = new Sunlight();Water water = new Water();return new Apple(appleSeed, sunlight, water);case "梨子":return new Pear();default:throw new IllegalArgumentException("暂时没有这种水果");}}
}

抽象工厂模式

高层是抽象类,定义通用属性和方法。具体实现类是靠继承的实现类实现

1.定义抽象类

public interface IFactory {Fruit create();
}

2.实现类

public class AppleFactory implements IFactory {@Overridepublic Fruit create(){return new Apple();}
}

抽象工厂模式适用于增加同类工厂这样的横向扩展需求,不适合新增功能这样的纵向扩展。

工厂模式主要用于封装对象的设计模式。

2.单例模式

饿汉式:

  • 变量在声明时便初始化。
public class Singleton {private static Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}
}

懒汉式:

  • 先声明一个空变量,需要用时才初始化。
public class Singleton {private static Singleton instance = null;private Singleton() {}public static Singleton getInstance(){if (instance == null) {instance = new Singleton();}return instance;}
}

还有一种比较常见的静态内部类方式保证懒汉式单例的线程安全:

public class Singleton {private static class SingletonHolder {public static Singleton instance = new Singleton();}private Singleton() {}public static Singleton getInstance() {return SingletonHolder.instance;}
}
  • 它能够避免对象重复创建,节约空间并提升效率
  • 避免由于操作不同实例导致的逻辑错误

一般的建议是:对于构建不复杂,加载完成后会立即使用的单例对象,推荐使用饿汉式。对于构建过程耗时较长,并不是所有使用此类都会用到的单例对象,推荐使用懒汉式。

3.建造型模式

链式调用生成不同的配置

public class MilkTea {private final String type;private final String size;private final boolean pearl;private final boolean ice;private MilkTea(Builder builder) {this.type = builder.type;this.size = builder.size;this.pearl = builder.pearl;this.ice = builder.ice;}public String getType() {return type;}public String getSize() {return size;}public boolean isPearl() {return pearl;}public boolean isIce() {return ice;}public static class Builder {private final String type;private String size = "中杯";private boolean pearl = true;private boolean ice = false;public Builder(String type) {this.type = type;}public Builder size(String size) {this.size = size;return this;}public Builder pearl(boolean pearl) {this.pearl = pearl;return this;}public Builder ice(boolean cold) {this.ice = cold;return this;}public MilkTea build() {return new MilkTea(this);}}
}

使用建造者模式的好处是不用担心忘了指定某个配置,保证了构建过程是稳定的

4.原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

public class MilkTea {public String type;public boolean ice;protected MilkTea clone() {MilkTea milkTea = new MilkTea();milkTea.type = this.type;milkTea.ice = this.ice;return milkTea;}
}

2.结构型模式

  • 适配器模式

适配器模式适用于 有相关性但不兼容的结构

class HomeBattery {int supply() {// 家用电源提供一个 220V 的输出电压return 220;}
}
class Adapter {int convert(int homeVolt) {// 适配过程:使用电阻、电容等器件将其降低为输出 5Vint chargeVolt = homeVolt - 215;return chargeVolt;}
}
public class User {@Testpublic void chargeForPhone() {HomeBattery homeBattery = new HomeBattery();int homeVolt = homeBattery.supply();System.out.println("家庭电源提供的电压是 " + homeVolt + "V");Adapter adapter = new Adapter();int chargeVolt = adapter.convert(homeVolt);System.out.println("使用适配器将家庭电压转换成了 " + chargeVolt + "V");USBLine usbLine = new USBLine();usbLine.charge(chargeVolt);}
}
  • 桥接模式

将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体模式或接口模式。

这个例子中将形状和颜色分离,根据需要对形状和颜色进行组合

//新建接口类 IColor,仅包含一个获取颜色的方法:public interface IColor {String getColor();
}
//每种颜色都实现此接口:public class Red implements IColor {@Overridepublic String getColor() {return "红";}
}public class Blue implements IColor {@Overridepublic String getColor() {return "蓝";}
}public class Yellow implements IColor {@Overridepublic String getColor() {return "黄";}
}public class Green implements IColor {@Overridepublic String getColor() {return "绿";}
}//在每个形状类中,桥接 IColor 接口:class Rectangle implements IShape {private IColor color;void setColor(IColor color) {this.color = color;}@Overridepublic void draw() {System.out.println("绘制" + color.getColor() + "矩形");}
}class Round implements IShape {private IColor color;void setColor(IColor color) {this.color = color;}@Overridepublic void draw() {System.out.println("绘制" + color.getColor() + "圆形");}
}class Triangle implements IShape {private IColor color;void setColor(IColor color) {this.color = color;}@Overridepublic void draw() {System.out.println("绘制" + color.getColor() + "三角形");}
}//测试函数:@Test
public void drawTest() {Rectangle rectangle = new Rectangle();rectangle.setColor(new Red());rectangle.draw();Round round = new Round();round.setColor(new Blue());round.draw();Triangle triangle = new Triangle();triangle.setColor(new Yellow());triangle.draw();
}
  • 组合模式

整体与部分的结构,当整体与部分有相似的结构,在操作时可以被一致对待时,就可以使用组合模式。

public abstract class Component {// 职位private String position;// 工作内容private String job;public Component(String position, String job) {this.position = position;this.job = job;}// 做自己的本职工作public void work() {System.out.println("我是" + position + ",我正在" + job);}abstract void addComponent(Component component);abstract void removeComponent(Component component);abstract void check();
}
//管理者继承自此抽象类:public class Manager extends Component {// 管理的组件private List<Component> components = new ArrayList<>();public Manager(String position, String job) {super(position, job);}@Overridepublic void addComponent(Component component) {components.add(component);}@Overridevoid removeComponent(Component component) {components.remove(component);}// 检查下属@Overridepublic void check() {work();for (Component component : components) {component.check();}}
}
//职员同样继承自此抽象类:public class Employee extends Component {public Employee(String position, String job) {super(position, job);}@Overridevoid addComponent(Component component) {System.out.println("职员没有管理权限");}@Overridevoid removeComponent(Component component) {System.out.println("职员没有管理权限");}@Overridevoid check() {work();}
}
//修改客户端如下:public class Client {@Testpublic void test(){Component boss = new Manager("老板", "唱怒放的生命");Component HR = new Employee("人力资源", "聊微信");Component PM = new Manager("产品经理", "不知道干啥");Component CFO = new Manager("财务主管", "看剧");Component CTO = new Manager("技术主管", "划水");Component UI = new Employee("设计师", "画画");Component operator = new Employee("运营人员", "兼职客服");Component webProgrammer = new Employee("程序员", "学习设计模式");Component backgroundProgrammer = new Employee("后台程序员", "CRUD");Component accountant = new Employee("会计", "背九九乘法表");Component clerk = new Employee("文员", "给老板递麦克风");boss.addComponent(HR);boss.addComponent(PM);boss.addComponent(CFO);PM.addComponent(UI);PM.addComponent(CTO);PM.addComponent(operator);CTO.addComponent(webProgrammer);CTO.addComponent(backgroundProgrammer);CFO.addComponent(accountant);CFO.addComponent(clerk);boss.check();}
}
  • 装饰模式

  • 增强一个类原有的功能
//新建颜值接口:public interface IBeauty {int getBeautyValue();
}
//新建 Me 类,实现颜值接口:public class Me implements IBeauty {
​@Overridepublic int getBeautyValue() {return 100;}
}
//戒指装饰类,将 Me 包装起来:public class RingDecorator implements IBeauty {private final IBeauty me;
​public RingDecorator(IBeauty me) {this.me = me;}
​@Overridepublic int getBeautyValue() {return me.getBeautyValue() + 20;}
}
  • 为一个类添加新的功能
//新建房屋接口:public interface IHouse {void live();
}
//房屋类:public class House implements IHouse{
​@Overridepublic void live() {System.out.println("房屋原有的功能:居住功能");}
}
新建粘钩装饰器接口,继承自房屋接口:public interface IStickyHookHouse extends IHouse{void hangThings();
}
//粘钩装饰类:public class StickyHookDecorator implements IStickyHookHouse {private final IHouse house;
​public StickyHookDecorator(IHouse house) {this.house = house;}
​@Overridepublic void live() {house.live();}
​@Overridepublic void hangThings() {System.out.println("有了粘钩后,新增了挂东西功能");}
}

纯粹的适配器模式 仅用于改变接口,不改变其功能,部分情况下我们需要改变一点功能以适配新接口。但使用适配器模式时,接口一定会有一个 回炉重造 的过程。

装饰模式 不改变原有的接口,仅用于增强原有功能或添加新功能,强调的是 锦上添花

  • 外观模式

将多个子系统封装起来,提供一个更简洁的接口供外部调用。

//新建浏览器类:public class Browser {public static void open() {System.out.println("打开浏览器");}
​public static void close() {System.out.println("关闭浏览器");}
​}
//新建 IDE 类:public class IDE {public static void open() {System.out.println("打开 IDE");}
​public static void close() {System.out.println("关闭 IDE");}
}
//新建微信类:public class Wechat {public static void open() {System.out.println("打开微信");}
​public static void close() {System.out.println("关闭微信");}
}
public class Facade {public void open() {Browser.open();IDE.open();Wechat.open();}
​public void close() {Browser.close();IDE.close();Wechat.close();}
}
  • 享元模式

享元模式体现的是 程序可复用 的特点,为了节约宝贵的内存,程序应该尽可能地复用,就像《极限编程》作者 Kent 在书里说到的那样:Don't repeat yourself. 简单来说 享元模式就是共享对象,提高复用性

  • 代理模式

给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

静态代理:

//新建网络请求接口:public interface IHttp {void request(String sendData);
​void onSuccess(String receivedData);
}
//新建 Http 请求工具类:public class HttpUtil implements IHttp {@Overridepublic void request(String sendData) {System.out.println("网络请求中...");}
​@Overridepublic void onSuccess(String receivedData) {System.out.println("网络请求完成。");}
}
//新建 Http 代理类:public class HttpProxy implements IHttp {private final HttpUtil httpUtil;
​public HttpProxy(HttpUtil httpUtil) {this.httpUtil = httpUtil;}
​@Overridepublic void request(String sendData) {httpUtil.request(sendData);}
​@Overridepublic void onSuccess(String receivedData) {httpUtil.onSuccess(receivedData);}
}

动态代理

public class HttpProxy implements InvocationHandler {private HttpUtil httpUtil;
​public IHttp getInstance(HttpUtil httpUtil) {this.httpUtil = httpUtil;return (IHttp) Proxy.newProxyInstance(httpUtil.getClass().getClassLoader(), httpUtil.getClass().getInterfaces(), this);}
​// 调用 httpUtil 的任意方法时,都要通过这个方法调用@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;if (method.getName().equals("request")) {// 如果方法名是 request,打印日志,并调用 request 方法System.out.println("发送数据:" + args[0]);result = method.invoke(httpUtil, args);} else if (method.getName().equals("onSuccess")) {// 如果方法名是 onSuccess,打印日志,并调用 onSuccess 方法System.out.println("收到数据:" + args[0]);result = method.invoke(httpUtil, args);}return result;}
}

动态代理本质上与静态代理没有区别,它的好处是 节省代码量。比如被代理类有 20 个方法,而我们只需要控制其中的两个方法,就可以用动态代理通过方法名对被代理类进行动态的控制,而如果用静态方法,我们就需要将另外的 18 个方法也写出来,非常繁琐。这就是动态代理的优势所在。

差别:装饰模式是为了 增强功能或添加功能,代理模式主要是为了加以控制

设计模式学习Day1(来自于知乎力扣官方)相关推荐

  1. int类型年月怎么区间查询_LeetCode 力扣官方题解 | 57.插入区间

    点击上方蓝字设为星标 下面开始今天的学习-力扣  57. 插入区间(点击文末阅读原文查看题目)题目描述给出一个无重叠的 ,按照区间起始端点排序的区间列表.在列表中插入一个新的区间,你需要确保列表中的区 ...

  2. 将矩阵转为一行_LeetCode 力扣官方题解 | 861. 翻转矩阵后的得分

    点击上方蓝字设为星标 下面开始今天的学习- 力扣  861. 翻转矩阵后的得分(点击文末阅读原文查看题目)题目描述有一个二维矩阵 A 其中每个元素的值为 0 或 1 .移动是指选择任一行或列,并转换该 ...

  3. java邮箱验证正则表达式_LeetCode 力扣官方题解 | 468.验证 IP 地址

    点击上方蓝字设为星标 下面开始今天的学习-力扣 468. 验证 IP 地址(点击文末阅读原文查看题目)题目描述 编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址. IPv4 地 ...

  4. leetcode c++未初始化_LeetCode 力扣官方题解 | 538. 把二叉搜索树转换为累加树

    力扣 538. 把二叉搜索树转换为累加树(点击查看题目) 力扣​leetcode-cn.com 题目描述 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater ...

  5. 力扣学习记录(每日更新)

    文章目录 引言 简单 力扣:1 两数之和 力扣:20 有效的括号 力扣:21 合并两个有序链表 力扣:22 括号生成 力扣:27 移除元素 力扣: 35 搜索插入位置 力扣:70 [爬楼梯](http ...

  6. 几乎刷完了力扣所有的树题,我发现了这些东西

    点击蓝色"力扣加加"关注我哟 加个"星标",带你揭开算法的神秘面纱! ❝ 这是力扣加加第「28」篇原创文章 先上下本文的提纲,这个是我用 mindmap 画的一 ...

  7. 力扣热门题目简单部分合集(共23道)

    文章目录 前言 1.两数之和(哈希表,双指针,数组) 2.有效的括号(栈,哈希表) 3.合并两个有序链表(递归,迭代) 4.最大子数组和(动态规划,分治,贪心) 5.爬楼梯(迭代,递归,动态规划,数学 ...

  8. 力扣刷题记录-动态规划问题总结

    百度百科里对于动态规划问题是这样解释的: 在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果.因此各个阶段 ...

  9. 《LeetCode力扣练习》第14题 C语言版 (做出来就行,别问我效率。。。。)

    库你急哇,哈集美马戏特~~ 只会暴力解法的我留下了没有技术含量的泪 这道题采用的是横向扫描,算法还是不难,但是可以借此题去学习一下二维char数组在函数间的传递,要是不会这个的话,自己是没有办法测试的 ...

最新文章

  1. mysql加删查语句_MySQL基本语句——增、删、查、改
  2. OpenGL画图设备上下文与MFC设备上下文的对应
  3. 电脑网页打不开但qq能上解决方法
  4. optional空值判断_Java 8 Optional不仅用于替换空值
  5. 最全介绍Document对象内容集合
  6. socket-(2)
  7. 无向图java_Java实现无向图的建立与遍历
  8. Win10无法访问Ubuntu18.04的smb解决
  9. Elmedia Player Pro Mac使用技巧,Elmedia键盘快捷键
  10. M study summarize
  11. java listbook,java,_Java泛型问题,在编译时,提示警告: 需要: ListT 找到: ListBookDetails,java - phpStudy...
  12. linux b类地址设24位掩码,CIDR,子网掩码以及划分子网超网
  13. 【mean teacher】RuntimeError: Integer division of tensors using div or / is no longer suppor的解决
  14. QT编译Python问题:During startup program exited with code 0xc0000135
  15. 笔记本电脑桌面便签哪个软件好用,桌面便签软件下载
  16. amd和英伟达运行linux,AMD Ryzen平台与P106 矿卡安装Ubuntu系统和CUDA环境
  17. Chrome浏览器设置 【显示右上角 翻译语言图标】
  18. 最新修复众人帮/蚂蚁帮任务平台系统源码+好看全新UI
  19. Oracle trace level
  20. Eclipse启动报错:org.eclipse.e4.core.di.InjectionException: java.lang.NoClassDefFoundError: javax/annotat

热门文章

  1. Verilog 代码编写 FPGA 数字CMI编码
  2. Android 设置飞行模式,判断是否是飞行模式
  3. 电脑搜不到自家wifi
  4. 第一节 gRPC概述
  5. 计算机考研432有哪些大学,考研百态,有学校录取94人让658人来复试,有学生初试432复试被刷...
  6. Android检测程序崩溃框架CustomActivityOnCrash
  7. 操作系统安全 访问控制机制
  8. 多云战略:如何通过多云实现数字化转型?
  9. 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
  10. Fluent算例4:脏几何处理的歧管