双向依赖问题
![1e0ec9563997464311bb4b9928f4fc82.png](https://i-blog.csdnimg.cn/blog_migrate/8ee630422b5e577eefdf534e7f74b7ec.jpeg)
![70488b92950c936e7fa1a4f736ad96b2.png](https://i-blog.csdnimg.cn/blog_migrate/a402642bf9b6da78f46cf0278ea40f15.jpeg)
![1314071667e3dcdb4af1f4994222addd.png](https://i-blog.csdnimg.cn/blog_migrate/e3bbdcb5486ec734d3fafcbdc54263eb.jpeg)
编译错误:
![5fe24e93c2e66967b900d42587485534.png](https://i-blog.csdnimg.cn/blog_migrate/32438c045c1ebf1d0a052bc801c22cfa.jpeg)
双向依赖问题——通过宏防止头文件重复包含
![16a7c66f08575d0164a29cf9b3ad5a42.png](https://i-blog.csdnimg.cn/blog_migrate/672a10b88f5aeb6ee7681ca806a4936b.jpeg)
![774e2dc2284ba08fe75b1e751e7e140f.png](https://i-blog.csdnimg.cn/blog_migrate/3fb078036bc79fc8d3504673093ad119.jpeg)
![fa317793460f460b118f0f177de71af0.png](https://i-blog.csdnimg.cn/blog_migrate/a7443fcdcb28799716d9f7e6a7757657.jpeg)
通过宏无法解决双向依赖的问题:
![7b4fdbafa8780281c54189b22afc357e.png](https://i-blog.csdnimg.cn/blog_migrate/caed387146e63f4f11e8168553a881b9.jpeg)
双向依赖解决方案
类B在类A之前被定义(在定义类A之前必须包含类B的头文件或完整的声明代码):
1.类A继承自类B;
2.类A聚合了类B的对象;
3.类A的头文件中使用了类B的属性或方法;
在C++语言里,如果一定需要双向依赖,那么至少有一个方向的关系必须是用指针实现的弱依赖关系。如果类A的头文件中只定义了类B的一个指针,没有使用类B中的任何属性和方法,C++编译器就不要求类B在类A之前被定义了。在定义类A时只需要告诉编译器还有一个类B的存在。
![1be08fd749b107ac775b87d3dd5d5250.png](https://i-blog.csdnimg.cn/blog_migrate/db2e0f634f9af75eae8ad61ea2da2f1d.jpeg)
![d3e6daa408bc2685c2d0da5df8c3fe12.png](https://i-blog.csdnimg.cn/blog_migrate/fc5e486e955e132e213c127704c78708.jpeg)
![96e86a25aac1564b9e73b40306bb6710.png](https://i-blog.csdnimg.cn/blog_migrate/93f39dc212c9b3246054ebdbd6ae16dd.jpeg)
![93362758700cafd501ab4e9e2e297c93.png](https://i-blog.csdnimg.cn/blog_migrate/459ead58a4ba052337ff8aa7ecdb0466.jpeg)
包的双向依赖问题
双向依赖会造成软件代码之间、组件之间、包或子系统之间的强烈耦合关系,对于需要适应不同需求和不同平台的系统,当相互依赖的两个包之间,任何一个包的接口发生变化,另一个包就要相应地进行修改。
观察者模式设计意图
1.定义对象之间多对一的依赖关系,也即多个对象依赖于一个对象的关系,同事保证,当被依赖的对象状态发生变化时,所有的依赖者会被自动地通知。(出版-订阅模式)
被依赖的对象向外发布自己的状态,而此前订阅了该状态的所有对象都会得到通知——这其实类似于一种消息在对象间的广播。
2.当一个对象需要通知另外一些对象,而你无法预知某些对象将被通知时,通过观察者模式就可以减弱通知对象和被通知对象之间的耦合关系。
3.当一个模块(模块A)的变化需要另一个模块(模块B)做出相应的修改,而你不知道有多少个类会被修改时,使用观察者模式就可以切断这种依赖关系,即模块A的变化不再影响模块B,模块B也无需做任何修改。模块B对模块A的依赖关系由直接依赖转变为间接依赖,具体的依赖关系是由模块A动态设定的。因此两个模块可以在互不干扰的情况下,相对独立地被复用和修改。
观察者模式——基本结构
![c9ba37d8114d66db0727cfd0d46aa568.png](https://i-blog.csdnimg.cn/blog_migrate/aa413444d1c272fb34bcca9103bfcfe5.jpeg)
1.主体类:被观察者类的基类,它管理所有的观察者,并提供添加和删除观察者的方法,观察者的数量一般不受限制;
2.观察者类:定义一个通知接口用以接收主体类发来的通知消息;
3.具体的主体类:具体的被观察类,它针对不同的需求,实现具体的主体属性和方法,决定何时发送通知消息等。
4.具体的观察者类:针对不同的需求,实现具体的通知接口,以接受具体的主体类发来的通知消息,并可以根据需要对消息进行特定的处理。
观察者模式——实现方式(Java)
![2489dde434398dba988b1d9e08a721b0.png](https://i-blog.csdnimg.cn/blog_migrate/01a2ab64c906355dded18b56e2069644.jpeg)
![a427e2294ebb29d747045db573d90051.png](https://i-blog.csdnimg.cn/blog_migrate/922bdafee281aab6255484f38b7e073f.jpeg)
![7773c9c56c231f5855c301134426f74d.png](https://i-blog.csdnimg.cn/blog_migrate/b949d1a8d1f8e351487451ec48167511.jpeg)
![dde66e0272a57beb2994768a0538ebae.png](https://i-blog.csdnimg.cn/blog_migrate/4afa2cd5dcce3177bac6024fc2688d71.jpeg)
![f15125df8397e70f2760e9d2460320a8.png](https://i-blog.csdnimg.cn/blog_migrate/2e9372e92d57b69eb38ee265dcf3e851.jpeg)
观察者模式——实现方式(C++)
![2ddc0e7e7326631a9b48ed3fd61186e1.png](https://i-blog.csdnimg.cn/blog_migrate/7d9321179de7d23fe85e6e4219cd20a1.jpeg)
![30d9aea74e04992fa1ac07df961398ba.png](https://i-blog.csdnimg.cn/blog_migrate/9d270c63a274030c3ec0c125a0f61937.jpeg)
![06d036c978fb34a7b9a2ffab06afd630.png](https://i-blog.csdnimg.cn/blog_migrate/26c42f2b6c9813bf03e80374ccdd4e10.jpeg)