版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014267209/article/details/52524922
设计模式:
1.定义:
是一套被反复使用.多数人只晓的.经过分类编目的.代码设计经验的总结
2.目的:
使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性
3.分类(23种):
创建型模式(5种):单例模式.抽象工厂模式.建造者模式.工厂模式.原型模式
结构型模式(7种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(11种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
一.单例模式(Singleton)
1.作用:
保证整个应用程序中某个实例有且只有一个
2.常见的单例对象:
配置文件.工具类.线程池.缓存.日志对象等
3.分类:
饿汉模式: 类加载后便会创建实例,不管用户是否获取
懒汉模式:成员变量只声明不实例化,在第一个用户获取该实例的时候才会创建
4.实现过程
1.将构造方法私有化,不允许外部直接创建对象
2.自己创建类的唯一实例,并且使用私有的静态的成员变量 private static
3.对象暴露一个用于获取实例的静态方法 public static
5.饿汉模式和懒汉模式的区别
饿汉模式加载类的时候比较慢,但是获取比较快,而且是线程安全的
懒汉模式加载类的时候比较快,但是获取比较慢,而且是线程不安全
二.工厂模式
1.概念:
->实例化对象,用工厂方法代替new操作
->工厂模式包括工厂方法模式和抽象工厂模式
->抽象工厂模式是工厂方法模式的扩展
2.意图:
->定义一个接口来创建对象,但是让子类来决定哪些类需要实例化
->工厂方法把实例化的工作推迟到子类中去实现
3.应用场景:
->有一组类似的对象需要创建
->在编码时不能预见需要创建哪种类的实例
->系统需要考虑扩展性, 不应依赖于产品类实例如何被创建.组合和表达的细节
4.设计思想:
->尽量松耦合,一个对象的依赖对象的变化与本身无关
->具体产品与客户端剥离,责任分割
5.好处:
-> 系统可以在不修改具体工厂角色的情况下引进新的产品
-> 客户端不必关心对象如何创建,明确职责
-> 更好的理解面向对象的原则 面向接口编程 而不是面向实现编程
6.常见应用:
JDBC.Spring BeanFactory.
7.工厂方法模式和抽象工厂模式对比
-> 工厂模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广
-> 工厂模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构
-> 工厂模式只是一个抽象的产品类,而抽象工厂模式有多个抽象产品类
三.观察者模式
1.介绍:
对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖与它的对象都得到通知并自动更新
2. 结构:
Subject:对象
Observe:观察者
3. 步骤:
第一:是目标对象的定义
第二:是具体的目标对象的定义
第三:观察者的接口定义
第四:观察者的具体实现
实例代码:
----------对象
public class WeatherSubject {
private List<Observer> observers = new ArrayList<>();
// 添加观察者
public void attach(Observer observer) {
observers.add(observer);
}
// 删除观察者
public void detach(Observer observer) {
observers.remove(observer);
}
protected void notifyObservers() {
for (Observer observer : observers) {
observer.update(this);
}
}
}
----------对象实现类
public class WeatherSubjectImpl extends WeatherSubject {
private String weatherContent;
public String getWeatherContent() {
return weatherContent;
}
public void setWeatherContent(String weatherContent) {
this.weatherContent = weatherContent;
this.notifyObservers(); // 值改变的时候触发通知方法
}
}
----------观察者接口
public interface Observer {
void update(WeatherSubject weather);
}
----------观察者接口的实现类
public class ObserverImpl implements Observer {
private String observerName;
private String weatherContent;
private String remindThing;
@Override
public void update(WeatherSubject weather) {
weatherContent = ((WeatherSubjectImpl) weather).getWeatherContent();
System.out.println(observerName + "收到了" + weatherContent + "," + remindThing);
}
public String getObserverName() {
return observerName;
}
public void setObserverName(String observerName) {
this.observerName = observerName;
}
public String getWeatherContent() {
return weatherContent;
}
public void setWeatherContent(String weatherContent) {
this.weatherContent = weatherContent;
}
public String getRemindThing() {
return remindThing;
}
public void setRemindThing(String remindThing) {
this.remindThing = remindThing;
}
}
----------观察者模式测试类
public class Client {
public static void main(String[] args) {
// 1.创建目标
WeatherSubjectImpl weather = new WeatherSubjectImpl();
// 2.创建观察者
ObserverImpl observerGirl = new ObserverImpl();
observerGirl.setObserverName("女朋友");
observerGirl.setRemindThing("使我们的第一次约会,地点街心公园,不见不散哦~");
ObserverImpl observerMum = new ObserverImpl();
observerMum.setObserverName("老妈");
observerMum.setRemindThing("是一个购物的好日子,明天去天虹扫货");
// 3.注册观察者
weather.attach(observerGirl);
weather.attach(observerMum);
// 4.目标发布天气
weather.setWeatherContent("明天天气晴朗,蓝天白云,天气28度");
}
}
4.分类:
推模型:按需将内容作为update的参数推送给观察者,会使观察者无法复用
拉模型:通常是将this传递给观察者,可以适用各种情况
5.可以使用Java自带的观察者信息
----------观察者类,实现Observer
public class WeatherObserver implements Observer {
private String observerName;
@Override
public void update(Observable o, Object arg) {
System.out.println(observerName + "收到了消息,目标推送过来的是" + arg);
System.out.println(observerName + "收到了消息,主动拉到" + ((WeatherSubject) o).getContent());
}
public String getObserverName() {
return observerName;
}
public void setObserverName(String observerName) {
this.observerName = observerName;
}
}
----------目标类,实现Observale
//天气目标的具体实现类
public class WeatherSubject extends Observable {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
this.setChanged();
this.notifyObservers(content);//推模式
// this.notifyObservers();//拉模式
}
}
----------测试类
public static void main(String[] args) {
WeatherSubject weather = new WeatherSubject();
WeatherObserver girlObserver = new WeatherObserver();
girlObserver.setObserverName("女朋友:");
WeatherObserver mumObserver = new WeatherObserver();
mumObserver.setObserverName("老妈:");
weather.addObserver(girlObserver);
weather.addObserver(mumObserver);
weather.setContent("天气晴朗,气温28度!");
}
6.什么情况下使用观察者模式
1.当一个抽象模型有两个方面,其中一个方便的操作依赖于另一个方面的状态变化
2.如果在更改一个对象的时候,需要同事连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变
3.当一个对象必须通知其他的对象,但是你又希望这个对象和其他被它通知的对象是松散耦合的.