**
1、策略模式
对于分支语句,尽量使用策略模式来增加代码的可复用性,
使用父类指针指向不同的子类对象来实现不同的功能。
子类对象通过工厂给我们。
**
**
2、观察者模式
如果A要时时刻刻通知B信息,可以在A中直接对B进行操作,但是代码复用性很差。如果后期想改成C,D,还需要进入A中修改代码。
可以抽象一个虚基类(接口),A中有接口的指针,可以指向不同的子类,在A中调用接口的方法,就可以实现多态。
**
**
3、装饰模式
过多使用继承也会带来代码的臃肿。
现在有字节流A类,
可以有子类文件流B,网络流C
B和C分别又有加密文件流D,缓冲文件流E,加密网络流F,加密网络流G。
等等等等。。。可见继承会带来过多的代码臃肿。
使用装饰模式,
A * a = new A();
B* b= new B(b);
D * d = new D(b);
d->方法;运行时装配,根据需要选择进行一层层进行封装(装饰)
**
4、桥模式
5、单例模式与reorder
有的类只能有一个实例化对象,如何保证呢?
把默认的无参构造函数和拷贝构造函数都设置成priviate的就可以了。
使用方法来返回实例化对象的指针。
class A{
private:
A instance;
A();
A(A);
public:
A* getinstance(){
if(instance==null)instance=new A();//初次创建实例化对象
return instance;
}
但是这方法是线程不安全的。如果多线程同时getinstance就会创建出多个实例。因此必须要加锁
A* getinstance(){
lock();
if(insance==null)instance =new A();
unlock();
return instance;
}
但是加锁对于高并发会大大浪费时间。
使用双检查锁,如果instance已经存在就直接返回,如果不存在才需要加锁,创建实例化
A* getinstance (){
if(instance ==null){
lock();
if(instance =null)instance = new A();
unlock();
}
return instance ;
}
但是还有问题,因为在new A实例化时,先分配内存,在构造,在把地址返回,但是这个顺序不是一定的,有可能线程1先把地址返回,在分配内存,在构造,此时线程2看到instance 不是null就返回了,结果instance还不能用,就报错。
因此就有了volatile关键字,volatile关键字的作用就是此对象实例化只能按照先分配内存,在构造,再返回地址的顺序来创建对象。因此需要把instance加上volatile关键字。
}
}
volatile作用
在工作内存中,每次使用 volatile变量 前必须先从主内存刷新最新的值,用于保证能看见其他线程对 volatile变量所做的修改。
在工作内存中,每次修改 volatile变量 后都必须立刻同步回主内存中,用于保证其他线程可以看到当前线程对 volatile变量 所做的修改。
volatile 所修饰的变量不能被指令重排序优化,从而保证代码的执行顺序和编写顺序相同。