1:单例模式

单例模式主要有3个特点,:

1、单例类确保自己只有一个实例。

2、单例类必须自己创建自己的实例。

3、单例类必须为其他对象提供唯一的实例。

单例模式也是一种比较常见的设计模式,它到底能带给我们什么好处呢?其实无非是三个方面的作用:

第一、控制资源的使用,通过线程同步来控制资源的并发访问;

第二、控制实例产生的数量,达到节约资源的目的。

第三、作为通信媒介使用,也就是数据共享,它可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。

使用案例:线程池、缓存、日志对象、打印机、显卡的驱动程序

2:装饰模式

装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

装饰模式和继承的关系:

装饰模式比继承要灵活。避免了继承体系臃肿。
而且降低了类于类之间的关系。

使用案例:io流:BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("text.txt"))));

3:工厂模式

首先,工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用 Class B ,那么A只是调用B的方法,而至于B的实例化,就交给工厂类。

其次,工厂模式可以降低代码重复。如果创建对象B的过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。我们可以这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的创建过程的修改维护。(当然,我个人觉得也可以把这些创建过程的代码放到类的构造函数里,同样可以降低重复率,而且构造函数本身的作用也是初始化对象。不过,这样也会导致构造函数过于复杂,做的事太多,不符合java 的设计原则。)

由于创建过程都由工厂统一管理,所以发生业务逻辑变化,不需要找到所有需要创建B的地方去逐个修正,只需要在工厂里修改即可,降低维护成本。同理,想把所有调用B的地方改成B的子类B1,只需要在对应生产B的工厂中或者工厂的方法中修改其生产的对象为B1即可,而不需要找到所有的new B()改为new B1()。

另外,因为工厂管理了对象的创建逻辑,使用者并不需要知道具体的创建过程,只管使用即可,减少了使用者因为创建逻辑导致的错误。

举个例子:

一个数据库工厂:可以返回一个数据库实例,可以是mysql,oracle等。

这个工厂就可以把数据库连接需要的用户名,地址,密码等封装好,直接返回对应的数据库对象就好。不需要调用者自己初始化,减少了写错密码等等这些错误。调用者只负责使用,不需要管怎么去创建、初始化对象。

还有,如果一个类有多个构造方法(构造的重写),我们也可以将它抽出来,放到工厂中,一个构造方法对应一个工厂方法并命名一个友好的名字,这样我们就不再只是根据参数的不同来判断,而是可以根据工厂的方法名来直观判断将要创建的对象的特点。这对于使用者来说,体验比较好。

4:模板方法

我理解的模板方法是:比如有一个银行办理业务案例,规定必须取号排队,操作(存钱,取钱,办卡等等),反馈评分。这个时候就需要定义一个模板方法比较合适了。模板方法定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。

什么时候用模板方法模式?

实现一些操作时,整体步骤很固定,但是呢。就是其中一小部分容易变,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

银行办理业务案例中的取号和最后的评分是不变的,但是中间的操作是容易改变的。

开发中常见场景:

其实,各个框架中,都有模板方法模式的影子。

数据库访问的封装

Junit单元测试

servlet中关于doGet/doPost方法的调用

Hibernate中模板程序

spring中JDBCTemplate,HibernateTemplate等等

注释:个人理解,像银行的例子取号和评分在模板里定义不是抽象的,一般用public,但是操作肯定是抽象方法。因为留给子类实现,同理,servlet中关于doGet/doPost方法,在其父类中也是抽象定义的,子类继承它必须要实现该方法。

5:观察者模式

参考地址:http://www.cnblogs.com/V1haoge/p/6513651.html

观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监听者,类似监听器的存在,一旦被观察/监听的目标发生的情况,就会被监听者发现,这么想来目标发生情况到观察者知道情况,其实是由目标奖情况发送到观察者的。

  观察者模式多用于实现订阅功能的场景,例如微博的订阅,当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。

关键点:

    1、针对观察者与被观察者分别定义接口,有利于分别进行扩展。

    2、重点就在被观察者的实现中:

      (1)定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)

      (2)定义通知方法,用于将新情况通知给观察者用户(订阅者用户)

    3、观察者中需要有个接收被观察者通知的方法。

  如此而已!

  观察者模式定义的是一对多的依赖关系,一个被观察者可以拥有多个观察者,并且通过接口对观察者与被观察者进行逻辑解耦,降低二者的直接耦合。

观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。

  1. 抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
  2. 具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  3. 抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
  4. 具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。

实现代码

抽象观察者(Observer)接口

public interface Observer {public void update(String msg, TextView tv);
}

具体观察者(Person)类

public class Person implements Observer {// 用户名private String name;public Person(String name) {this.name = name;}@Overridepublic void update(String msg, TextView tv) {tv.setText(tv.getText()+name+":"+ msg +"\n");}}

抽象主题(Subject)接口

public interface Subject {/*** 增加观察者* @param observer*/public void attach(Observer observer);/*** 删除观察者* @param observer*/public void detach(Observer observer);/*** 通知观察者*/public void notify(String message, TextView v);
}

具体主题(XiaosongSubject)类

public class XiaosongSubject implements Subject {//用于保存订阅了小嵩的博客的用户private List<Observer> mPersonList = new ArrayList<>();@Overridepublic void attach(Observer observer) {mPersonList.add(observer);}@Overridepublic void detach(Observer observer) {mPersonList.remove(observer);}@Overridepublic void notify(String message, TextView tv) {for (Observer observer : mPersonList) {observer.update(message,tv);}}
}

MainActivity类

public class MainActivity extends AppCompatActivity implements View.OnClickListener{private Person pMing,pQing,pLiang;private XiaosongSubject mSubject;private TextView tv_output;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initEvent();}private void initView() {findViewById(R.id.btn_add_one).setOnClickListener(this);findViewById(R.id.btn_add_two).setOnClickListener(this);findViewById(R.id.btn_add_three).setOnClickListener(this);findViewById(R.id.btn_notify).setOnClickListener(this);findViewById(R.id.btn_delete).setOnClickListener(this);tv_output = (TextView)findViewById(R.id.tv_output);}private void initEvent() {//创建被观察者(具体主题)mSubject = new XiaosongSubject();}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_add_one://注册观察者 小明if (pMing==null){pMing = new Person("小明");mSubject.attach(pMing);Toast.makeText(this,"小明关注了我",Toast.LENGTH_SHORT).show();}else {Toast.makeText(this,"小明已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();}break;case R.id.btn_add_two://注册观察者 小琴if (pQing==null){pQing = new Person("小琴");mSubject.attach(pQing);Toast.makeText(this,"小琴关注了我",Toast.LENGTH_SHORT).show();}else {Toast.makeText(this,"小琴已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();}break;case R.id.btn_add_three://注册观察者 阿亮if (pLiang==null){pLiang = new Person("阿亮");mSubject.attach(pLiang);Toast.makeText(this,"阿亮关注了我",Toast.LENGTH_SHORT).show();}else {Toast.makeText(this,"阿亮已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();}break;case R.id.btn_notify://主题(被观察者)更新了内容,通知所有观察者tv_output.setText("");mSubject.notify("小嵩更新微博啦~ 快来看看吧", tv_output);break;case R.id.btn_delete://注销观察者 小明if (pMing!=null){mSubject.detach(pMing);pMing = null;}if (pQing!=null){//注销观察者 小琴mSubject.detach(pQing);pQing = null;}if (pLiang!=null){//注销观察者 阿亮mSubject.detach(pLiang);pLiang = null;}break;default:break;}}
}

后续补上一些适配器模式,桥梁模式,责任链模式等等。

浅谈自己理解的几种设计模式相关推荐

  1. 浅谈javaweb三大框架和MVC设计模式

    浅谈javaweb三大框架和MVC设计模式 转载自:http://blog.csdn.net/sunpeng19960715/article/details/50890705 小序:博主以前在学jav ...

  2. 浅谈以太坊智能合约的设计模式与升级方法

    浅谈以太坊智能合约的设计模式与升级方法 1. 最佳实践 2. 实用设计案例 2.1 控制器合约与数据合约: 1->1 2.2 控制器合约与数据合约: 1->N 2.3 控制器合约与数据合约 ...

  3. 搞懂分布式技术16:浅谈分布式锁的几种方案

    搞懂分布式技术16:浅谈分布式锁的几种方案 前言 随着互联网技术的不断发展,数据量的不断增加,业务逻辑日趋复杂,在这种背景下,传统的集中式系统已经无法满足我们的业务需求,分布式系统被应用在更多的场景, ...

  4. oracle hash join outer,CSS_浅谈Oracle中的三种Join方法,基本概念 Nested loop join: Outer - phpStudy...

    浅谈Oracle中的三种Join方法 基本概念 Nested loop join: Outer table中的每一行与inner table中的相应记录join,类似一个嵌套的循环. Sort mer ...

  5. Ybtoj 最优密码 单调队列(浅谈)树状数组 两种解法

    作者:hsez_yyh 链接:https://blog.csdn.net/yyh_getAC/article/details/123956399  来源:湖北省黄石二中竞赛组  著作权归作者所有.商业 ...

  6. 浅谈Vue项目中用到的设计模式

    什么是设计模式: 设计模式的原则是找出程序中的变化,并将变化封装起来,实现高效的可复用性.核心在于意图,而不在结构.通过设计模式可以帮助我们增强代码的可重用性.可扩充性. 可维护性.灵活性.我们使用设 ...

  7. 快速理解二十三种设计模式(速记)

    设计模式六大原则 单一职责原则(Single Responsibility Principle) 里氏替换原则(Liskov Substitution Principle) 依赖倒置原则(Depend ...

  8. token干什么用_浅谈Token理解运用

    周末没带电脑,闲着也是闲着,出来分享一点东西,也当自己学习和巩固了. 今天分享一下Token的理解,首先Token的定义是什么? 概念 Token被翻译成为('令牌','标记')在计算机中的含义也差不 ...

  9. arm中断保护和恢复_浅谈ARM处理器的七种异常处理

    昨天的文章,我们谈了ARM处理器的七种运行模式,分别是:用户模式User(usr),系统模式System(sys),快速中断模式(fiq),管理模式Supervisor(svc),外部中断模式(irq ...

最新文章

  1. Java ClassLoader详解
  2. visual studio2019许可证
  3. libsvm 数据预处理 模块化程序
  4. poj 2362(剪枝)
  5. DCMTK:用于DICOM数据字典的哈希表接口
  6. iOS imageio nsurlsession 渐进式图片下载
  7. php如果实现日历的制作,教大家制作简单的php日历
  8. conda创建环境及激活环境失败问题
  9. 55.SQL server 行转列
  10. PAT (Basic Level) Practice1027 打印沙漏
  11. 互联网大厂跳槽鄙视链
  12. 无需编码生成信息系统_无需编码即可逐步进行花分类
  13. 移动光猫上插usb储存设备在终端系统中该如何设置才能共享里面的文件。新手,小白,求大神指点
  14. jquery 图片裁剪 java,jQuery实现图片上传和裁剪插件Croppie
  15. 手机rar压缩包解密,rar压缩包权限密码多少?
  16. 客户案例 | 初窥元宇宙,Oasis让更多人找到第二人生
  17. JS 数组,对象。中划线、数字属性时值获取
  18. JAVA重载函数求最大值
  19. 优启通桌面只有一个计算机,优启通图文详细使用教程,优启通使用教程
  20. 写给所有程序员的心声~千里马常有,但伯乐不常有

热门文章

  1. 计算机前沿知识论文,计算机前沿技术论文.pdf
  2. 一种全新的指令集架构RISC-V
  3. 组成微型计算机硬件桶的是,3_微型计算机统.ppt
  4. 和CSDN的七年之痒
  5. 开源leaflet地图组件的微信小程序版——leafletwx
  6. 立Flag 学习Ng - 高可用配置
  7. 独家分享,一位刚从新加坡回国的朋友最近半年在上海找工作的体验
  8. Oracle中预警表,Oracle DB 查看预警日志
  9. 理解ClassLoader
  10. moon服务器 zerotier_初探:建立 zerotier 的 moon 服务器