在学习设计模式前,我们先要弄明白一个问题,那就是为什么要学习设计模式?在JAVA领域,大部分使用的是贫血模型,业务逻辑都是service之间的调用,类似于函数式编程,其他高深的东西都封装于框架中,平时能用上设计模式的地方确实不多,似乎学习了也没啥用。

我觉得设计模式特别像九阳神功,练成「九阳神功」后,内力自生速度奇快,无穷无尽,普通拳脚也能使出绝大攻击力,学习了设计模式,虽然还是普通的功能,却在稳定性,可维护性上大不相同了。

九阳神功是融会贯通武学体系,练成后天下武学皆附拾可用。学会了设计模式,再看各种开源框架源码,就能融会贯通,明白作者为什么要这么写,并且为已所用。

设计模式总览

七大设计原则

开闭原则,软件实体应当对扩展开放,对修改关闭,扩展新类而不是修改旧类

里氏替换原则,继承必须确保超类所拥有的性质在子类中仍然成立,继承父类而不去改变父类

依赖倒置原则,高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象,面向接口编程,而不是面向实现类

单一职责原则,一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分,每个类只负责自己的事情,而不是变成万能

接口隔离原则,一个类对另一个类的依赖应该建立在最小的接口上,各个类建立自己的专用接口,而不是建立万能接口

迪米特法则,只与你的直接朋友交谈,不跟“陌生人”说话,无需直接交互的两个类,如果需要交互,使用中间者

合成复用原则,软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现

单例模式

一个单一的类,负责创建自己的对象,同时确保系统中只有单个对象被创建。

单例特点

某个类只能有一个实例;(构造器私有)

它必须自行创建这个实例;(自己编写实例化逻辑)

它必须自行向整个系统提供这个实例;(对外提供实例化方法)

使用场景

多线程中的线程池

数据库的连接池

系统环境信息

上下文(ServletContext) ......

接下去看下经典的懒汉模式的单例代码

public class SingleObject {//使用volatile保证内存可见性,防止指令重排private volatile static SingleObject instance;//私有构造器,外部无法newprivate SingleObject() {}public static SingleObject getInstance() {//判断是否已有实例,没有则创建实例if (instance == null) {//多线程情况下需要加锁synchronized (SingleObject.class) {//防止多个线程走到这里,所以还需要判断一次if (instance == null) {instance = new SingleObject();}}}return instance;}
}

工厂模式

提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。难点:写好我们的工厂

简单工厂

简单工厂的核心代码就是MouseFactory的createMouse,通过传入不同的type来返回不同的Mouse

public abstract class Mouse {public abstract void sayHi();public void test() {System.out.println("测试工作");}
}public class DellMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("DellMouse");}
}public class HpMouse extends Mouse {@Overridepublic void sayHi() {System.out.println("HpMouse");}
}public class SimpleMouseFactory {//创建mouse对象public static Mouse createMouse(int type) {Mouse mouse = null;if (type == 0) {mouse = new DellMouse();} else if (type == 1) {mouse = new HpMouse();} else {throw new IllegalArgumentException();}//出厂测试mouse.test();return mouse;}@Testpublic void testCreate() {Mouse mouse = createMouse(0);mouse.sayHi();mouse = createMouse(1);mouse.sayHi();}
}

现在思考一个问题,为什么要用工厂模式,而不是直接new一个HpMouse或者DellMouse呢?

首先,根据依赖倒置原则,我们应该依赖抽象,而不是具体的类,直接new一个就是依赖于具体的类了。其次工厂模式可以在产品出厂前做一些特殊处理,比如测试工作,这个很重要,Spring的很多重要功能都依赖于此。我们知道Spring里面有个bean工厂,而它生产的不是原始对象,而是代理对象,只有通过代理对象才能实现面向切面编程,后面的拦截器,事务处理等才有了实现的可能。理解了上面两点,也就理解了工厂模式。

简单工厂有个缺点就是如果添加新的产品,需要修改createMouse方法,也就违反了开闭原则。这个时候就可以使用工厂模式。

工厂模式

工厂模式就是把MouseFactory作为抽象类,每一种产品都新建一个工厂类,一个工厂类只生成一种产品,这样当有新的产品时,只需要新建一个工厂类就行了。

public abstract class MouseFactory {public abstract Mouse createMouse();static class HpMouseFactory extends MouseFactory {@Overridepublic Mouse createMouse() {return new HpMouse();}}static class DellMouseFactory extends MouseFactory {@Overridepublic Mouse createMouse() {return new DellMouse();}}public static void main(String[] args) {HpMouseFactory hpMouseFactory = new HpMouseFactory();DellMouseFactory dellMouseFactory = new DellMouseFactory();Mouse mouse = hpMouseFactory.createMouse();mouse.sayHi();mouse = dellMouseFactory.createMouse();mouse.sayHi();}
}

抽象工厂模式

工厂模式有个限制就是只能生产一类的产品,如果想又生产鼠标又生产键盘该怎么办呢?这时就要用到抽象工厂了,把生产鼠标和键盘的方法放在抽象工厂类中,下面的实现类来决定具体生产哪一种产品。

public abstract class PcFactory {abstract Mouse createMouse();abstract Keybo createKeybo();static class HpFactory extends PcFactory {@OverrideMouse createMouse() {return new HpMouse();}@OverrideKeybo createKeybo() {return new HpKeybo();}}static class DellFactory extends PcFactory {@OverrideMouse createMouse() {return new DellMouse();}@OverrideKeybo createKeybo() {return new DellKeybo();}}public static void main(String[] args) {DellFactory dellFactory = new DellFactory();Mouse mouse = dellFactory.createMouse();mouse.sayHi();Keybo keybo = dellFactory.createKeybo();keybo.sayHi();}
}

设计模式(一)--编程界的九阳神功相关推荐

  1. 程序员界的九阳神功与独孤九剑

    想写这篇文章已经很久了,可以说它是我很早以前就思考过的两个理念之一(另一个是"金字塔理论"),希望读过本文的人多多提出你们不同的看法,共同分享. -----------Lycos ...

  2. 编程基础知识真的是九阳神功吗?

    作者|大飞码字 来源|大飞码字(ID:BigFly1024) 有不少读者咨询过基础知识相关的问题. 有问怎么能够学好基础知识,有问基础知识到底有什么用,也有直接过来喷我,说工作只有CRUD,基础知识就 ...

  3. 基础知识真的是九阳神功吗?

    有不少读者咨询过基础知识相关的问题. 有问怎么能够学好基础知识,有问基础知识到底有什么用,也有直接过来喷我,说工作只有CRUD,基础知识就是忽悠. 当然,也有一种论调说,基础知识就像是编程中的九阳神功 ...

  4. 微软顶级代码女神,编程界最有权势的女王

    转载/码农翻身刘欣 提到程序员,联想到的就是格子衫.黑框眼镜.头发稀疏的男人形象,但程序员中不乏有女士的身影. 今年介绍一位在编程语言和编程工具界可能是最有权势的"女王" :微软全 ...

  5. 编程界“网络工程师”都用过的Python学习教程+PDF电子版曝光了

    编程界"网络工程师"都用过的Python学习教程+PDF电子版曝光了 网络工程师是通过学习和训练,掌握网络技术的理论知识和操作技能的网络技术人员.网络工程师能够从事计算机信息系统的 ...

  6. Python设计模式面向对象编程

    前言 本篇文章是基于极客时间王争的<设计模式之美>做的总结和自己的理解.   说到面向对象编程,作为一个合格的Pythoner,可以说信手拈来.毕竟在Python里"万物都是对象 ...

  7. 编程界称霸全球的10大算法,你到底了解几个呢?

    来源:课程图谱博客 本文约2300字,建议阅读9分钟 本文带你了解编程界称霸全球的十大算法. 算法究竟是什么? 简而言之,算法代表经过明确定义的计算过程,用于将输入转化为输出. 可以这样理解,算法是用 ...

  8. 22岁天才少女加入华为俄罗斯研究院,曾获「编程界奥赛」冠军

    来源:新智元  怎样才能称得上「天才少年」? 中小学期间横扫竞赛,还拿下了编程界奥赛ICPC的冠军. 值得一提的是,年仅22岁的她刚刚加入了华为. 这位女孩便是Valeria Ryabchikova. ...

  9. 高颜值俄罗斯天才少女加入华为,曾获“编程界的奥林匹克”世界冠军

    热门资讯早知道,吃瓜唠嗑不冷场, 记得加个星标,第一时间获得推送 来源:程序人生(ID:coder _life).图文编辑:xj 1月11日,据华为心声社区报道,曾获得"编程界的奥林匹克&q ...

  10. C++ 是 编程界 的 背锅侠

    C++ 是 编程界 的 背锅侠, C++ 背的包袱 之 庞大复杂, 举世瞩目, 令人感动 . C++  标准 委员会 俨然 已成了一个 职业 . C++  把  静态编译 体系 发展到 庞大复杂, C ...

最新文章

  1. php sf框架,GitHub - YanCastle/sf: php swoole framework
  2. c语言 字符串 正序再倒序_新特性解读 | MySQL 8.0 索引特性3 -倒序索引
  3. java实体类转map_十五道经典面试题-JAVA基础篇
  4. linux rsync 远程同步
  5. c#字符型转化为asc_wap站 utf-8与 gb2312字符编码的转化函数
  6. ubuntu Could not get lock /var/lib/dpkg/lock解决方法
  7. 小汤学编程之JavaEE学习day09——Mybatis
  8. ArrayList扩容
  9. js 异步函数讲解: Promise、async和await示例
  10. 嵌入式工作笔记0004---常见术语积累--随时更新
  11. plantuml最大宽度_设置TH最小和最大宽度非常缓慢
  12. Webpack——样式处理
  13. ISL - Ch.2 Statistical Learning
  14. 【语音隐写】基于matlab GUI DCT+DWT音频数字水印嵌入提取【含Matlab源码 836期】
  15. mysql连接池满了_《MySql体系结构与存储引擎》面试腾讯前总结
  16. 腾讯力作!iOS 9 人机界面指南(5):图标与图形设计
  17. 【日常篇】006_从黑体辐射到RGB——如何定量计算光谱的颜色?
  18. 使用VirtualBox创建Mac虚拟机
  19. Playframework介绍
  20. 名帖44 北魏 楷书《元苌墓志》

热门文章

  1. ES6 对象数组查找某一个对象
  2. 创维电视能用鸿蒙系统吗,鸿蒙OS系统电视怎么看直播?装了鸿蒙系统的电视可以看电视直播吗?当然可以...
  3. 《墨菲定律》——决策中的学问
  4. es管理器免root_国产应用也强大 ES文件浏览器增加ROOT管理
  5. HORNER(霍纳)法则的C实现以及算法比较 2.10
  6. Android 10.0在电话拨号盘(Dialer app中)通过暗码进入工厂测试模式
  7. 用canvas写 看你有多色 游戏
  8. 普及练习场 深度优先搜索 八皇后
  9. 【翻译】关于ADXL345连接指南
  10. He's a Pirate---David Garrett