前言: 前沿技术一直在迭代,有一种东西是不会更新的,那就是设计模式的思想。 可以来学习学习设计模式的思维,巧妙设计!
一、官方话语概述六大原则二、个人解读概述六大原则三、今日主题场景概述代码实现'主题'代码'观察者'代码'数据展示和test'代码四、读者须知
一、官方话语
概述
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
六大原则
- 单一职责原则 (Single ResponsiBility Principle) 概括:应该有且仅有一个原因引起类的变更
- 里氏替换原则(liskov Substitution Principle ) 概括:基类出现的地方,子类一定可以出现
- 依赖倒转原则(Depndece Inversion Principle) 概括:针对接口编程,依赖于抽象而不是具体
- 接口隔离原则(Interface Segregation Principle) 概括:使用多个隔离的接口,比使用单个接口好 (细分接口,降低耦合)
- 迪米特法则 (Demeter Principle) 概括:实体应当尽量少的与其他类发生互相作用,使得系统功能模块相对独立
- 开闭原则(Open Close Principle) 概括: 对扩展开放,对修改关闭
二、个人解读
概述
设计模式在代码层级中,是让你在某种业务场景刚开始设计时,能让未来的相关需求扩展极为方便的一个思想。
简单的说,在一开始设计好,扩展是很方便的,设计模式就是这个功劳者
。
对于我们本来就懒的开发人员来说,这是求之不得
的。
六大原则
而对于六大原则,简单过一下就行,不用刻意理解,如果你会了面向对象和设计模式的使用
,自然就遵循了。
三、今日主题
观察者模式: 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
场景
比如现在我管理多个相同仓库,我要更新它的长宽高(假设他们的长宽高都一致),并通知到这多个仓库。
概述
简单的说就是你更新了数据,要通知所有相关的人员。 这样的情况,我们可以采用观察者模式,有着多对1的关系,像维护数据库表那样维护,维护1比维护多要简单,便捷。 而在该模式中,好比一个主题(具备 观察者的 注册,更新,同步等)以及多个观察者,主题具体主动权去操作每个观察者。
代码实现
'主题'代码
代码语言:javascript复制package top.huey.designpattern.observerpattern.subject;
import top.huey.designpattern.observerpattern.observer.Observer;
/**
* @author huey
* @Description : 主题对象,管理观察者,出现任何更改,通知所有观察者,、
* 1主题,n观察者
* @Date Created in 2018/7/10 13:56
*/
public interface Subject {
/**
* 注册指定观察者
*/
void registerObserver(Observer observer);
/**
* 删除指定观察者
*/
void removeObserver(Observer observer);
/**
* 同步更新观察者
* 调用所有观察者的某个数据更新
* (如何通知先不管,暂时只是update)
*/
void notifyObserver();
}
/**
* @author huey
* @Description : 具体的主题对象
* @Date Created in 2018/7/11 11:50
*/
public class ConcreteSubject implements Subject {
/**
* 具体主题,依赖所有观察者,同步各种数据
*/
private List<Observer> observers;
/**
* 观察者 长属性
*/
private int length;
/**
* 观察者 宽属性
*/
private int weight;
/**
* 观察者 高属性
*/
private int high;
/**
* 对象初始化,初始化观察者集合对象
*/
public ConcreteSubject() {
observers = new ArrayList<>();
}
/**
* 模拟注册指定观察者
*
* @param observer
*/
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
/**
* 模拟删除指定观察者
*
* @param observer
*/
@Override
public void removeObserver(Observer observer) {
// observers.remove(observer);
int i = observers.indexOf(observer);
if (!StringUtils.isEmpty(i)) {
observers.remove(i);
}
}
/**
* 同步更新观察者
* 调用所有观察者的某个数据更新
* (如何通知先不管,暂时只是update)
*/
@Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(this.length,this.weight,this.high);
}
}
/**
* 对外设置All,同步
*/
public void setValue(int length, int weight, int high) {
this.length = length;
this.weight = weight;
this.high = high;
notifyObserver();
}
}
'观察者'代码
代码语言:javascript复制总结:perfect!如果你需要
扩展多个观察者
,只需要写出Observer的实现,然后在相应的实例化子类被主题注册即可。
package top.huey.designpattern.observerpattern.observer;
/**
* @author huey
* @Description : 观察者接口 具备实际更新行为
* @Date Created in 2018/7/11 11:29
*/
public interface Observer {
/**
* 当前观察者更新数据
* 参数为你要更新的参数
*/
void update(int ... length);
}
/**
* @author huey
* @Description : 根据需求更新哪些数据,此处更新length
* @Date Created in 2018/7/16 11:32
*/
public class Concrete2Display implements DisplayElement, Observer {
private int length;
private int weight;
private int high;
private Subject concreteSubject;
/**
* @param
* @return
* @description 注册
* @author: xiaoying@hexindai.com V1.0 2018/7/16 13:02
*/
public Concrete2Display(Subject concreteSubject) {
this.concreteSubject = concreteSubject;
concreteSubject.registerObserver(this);
}
/**
* 模拟更新
*
* @param
*/
@Override
public void update(int... arrs) {
this.length = arrs[0];
this.weight = arrs[1];
this.high = arrs[2];
this.display();
}
/**
* 展示数据
*/
@Override
public void display() {
System.out.println(this.getClass().toString() "----length: " this.length ",weight: " this.weight ",high: " this.high);
}
}
/**
* @author huey
* @Description : 根据需求更新哪些数据,此处更新length
* @Date Created in 2018/7/16 11:32
*/
public class ConcreteDisplay implements DisplayElement, Observer {
private int length;
private int weight;
private int high;
private Subject concreteSubject;
/**
* @param
* @return
* @description 注册
* @author: xiaoying@hexindai.com V1.0 2018/7/16 13:02
*/
public ConcreteDisplay(Subject concreteSubject) {
this.concreteSubject = concreteSubject;
concreteSubject.registerObserver(this);
}
/**
* 当前观察者更新数据
* 参数为你要更新的参数
*
* @param length
*/
@Override
public void update(int... length) {
this.length = length[0];
this.display();
}
/**
* 展示数据
*/
@Override
public void display() {
System.out.println(this.getClass().toString() "----length: " this.length ",weight: " this.weight ",high: " this.high);
}
}
'数据展示和test'代码
代码语言:javascript复制package top.huey.designpattern.observerpattern.display;
/**
* @author huey
* @Description : 数据展示
* @Date Created in 2018/7/11 11:48
*/
public interface DisplayElement {
void display();
}
/**
* @author huey
* @Description : 测试代码
* @Date Created in 2018/7/16 10:43
*/
public class TestObserver {
/**
* @author huey
* @Description : 多对1,实时通知
* @Date Created in 2018/7/16 14:06
*/
@Test
public void test1() {
/**
*创建主题
*/
ConcreteSubject concreteSubject = new ConcreteSubject();
/**
*注册当前观察者concreteDisplay到主题
*/
ConcreteDisplay concreteDisplay = new ConcreteDisplay(concreteSubject);
/**
*更新,通知多个观察者,展示
*/
System.out.println("-------begin--------");
concreteSubject.setValue(32, 1, 1);
/**
*注册第二个观察者到主题
*/
new Concrete2Display(concreteSubject);
/**
*更新,通知多个观察者,展示
*/
System.out.println("-------more--------");
concreteSubject.setValue(32, 2, 1);
/**
*删除第一个观察者到主题
*/
concreteSubject.removeObserver(concreteDisplay);
System.out.println("-------less--------");
concreteSubject.setValue(32, 1, 0);
}
}
四、读者须知
- 本
系列文章
内容会比较简陋,望有兴趣读者还是fork源码
,调试一下。(如果你看过该书,一定可以加深印象) - 联想下实际运用的哪些业务场景用到该模式,哪些中间件用到该模式,是否自己能在业务中使用。
- 即使你现在用不到某些设计模式,但是还是应该理解其原理的。
- 当时理解并不意味着自己已会,可以自己尝试练习,并幻想一种业务场景,画画类图,设计一下。
coding
时,做到了如何落实
;writing
时,做到了如何表达
;sharing
时,做到了如何传授
;thinking
时,做到了如何提升
;
代码请参考码云:https://gitee.com/tjhuey/GodingGroup 设计模式相关概念请参考:http://naotu.baidu.com/file/5811bf42020e6a2d877b992cfca90d26
本期撰稿人:huey
本期审稿人:聆小小
本期责任编辑:兔子