创建型设计模式
单例模式
它允许一个类有且仅有一个实例单例模式的优点:
在内存中只有一个对象,节省内存空间。
避免频繁的创建销毁对象,可以提高性能。
避免对共享资源的多重占用。
可以全局访问。
适用场景:
由于单例模式的以上优点,所以是编程中用的比较多的一种设计模式。我总结了一下我所知道的适合使用单例模式的场景:
需要频繁实例化然后销毁的对象。
创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
有状态的工具类对象。
频繁访问数据库或文件的对象。
以及其他我没用过的所有要求只有一个对象的场景。
单例模式注意事项:
只能使用单例类提供的方法得到单例对象,不要使用反射,否则将会实例化一个新对象。
不要做断开单例类对象与类中静态引用的危险操作。
多线程使用单例使用共享资源时,注意线程安全问题。
抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类工厂方法模式
Ceph中纠删码插件库的设计使用单例模式和工厂模式相结合的方式行为型设计模式
Visitor访问者模式
访问者模式是一种将算法与对象结构分离的软件设计模式。Ceph中,遍历操作pglog(LogEntryTrimmer),执行操作
默认的访问者基类:
class Visitor {
public:
virtual void append(uint64_t old_offset) {}
virtual void setattrs(map<string, boost::optional<bufferlist> > &attrs) {}
virtual void rmobject(version_t old_version) {}
virtual void create() {}
virtual void update_snaps(set<snapid_t> &old_snaps) {}
virtual void ec_overwrite(version_t write_version) {}
virtual ~Visitor() {}
};
访问者的算法:
void ObjectModDesc::visit(Visitor *visitor) const
{
bufferlist::iterator bp = bl.begin();
try {
while (!bp.end()) {
DECODE_START(1, bp);
uint8_t code;
::decode(code, bp);
switch (code) {
case APPEND: {
uint64_t size;
::decode(size, bp);
visitor->append(size);
break;
}
case SETATTRS: {
map<string, boost::optional<bufferlist> > attrs;
::decode(attrs, bp);
visitor->setattrs(attrs);
break;
}
case DELETE: {
version_t old_version;
::decode(old_version, bp);
visitor->rmobject(old_version);
break;
}
case CREATE: {
visitor->create();
break;
}
case UPDATE_SNAPS: {
set<snapid_t> snaps;
::decode(snaps, bp);
visitor->update_snaps(snaps);
break;
}
case EC_OVERWRITE: {
version_t write_version;
::decode(write_version, bp);
visitor->ec_overwrite(write_version);
break;
}
default:
assert(0 == "Invalid rollback code");
}
DECODE_FINISH(bp);
}
} catch (...) {
assert(0 == "Invalid encoding");
}
}
访问者基类的派生类:
struct DumpVisitor : public ObjectModDesc::Visitor {
Formatter *f;
DumpVisitor(Formatter *f) : f(f) {}
void append(uint64_t old_size) {
f->open_object_section("op");
f->dump_string("code", "APPEND");
f->dump_unsigned("old_size", old_size);
f->close_section();
}
void setattrs(map<string, boost::optional<bufferlist> > &attrs) {
f->open_object_section("op");
f->dump_string("code", "SETATTRS");
f->open_array_section("attrs");
for (map<string, boost::optional<bufferlist> >::iterator i = attrs.begin();
i != attrs.end();
++i) {
f->dump_string("attr_name", i->first);
}
f->close_section();
f->close_section();
}
void rmobject(version_t old_version) {
f->open_object_section("op");
f->dump_string("code", "RMOBJECT");
f->dump_unsigned("old_version", old_version);
f->close_section();
}
void create() {
f->open_object_section("op");
f->dump_string("code", "CREATE");
f->close_section();
}
void update_snaps(set<snapid_t> &snaps) {
f->open_object_section("op");
f->dump_string("code", "UPDATE_SNAPS");
f->dump_stream("snaps") << snaps;
f->close_section();
}
};
使用方式:DumpVisitor vis(f);
visit(&vis);
Observer观察者模式
观察者模式用于解决一个相当常见的问题:当某些其他对象改变状态时, 如果一组对象需要进行相应的更新,那么,应该如何处理呢?Observer模式的具体实现中,在被观察的对象中保持观察者的引用,如果被观察者的状态发生了变化, 则通过保持的引用调用观察者的update函数,以实现通知观察者的目的。
Ceph中动态识别参数变化,用的是observer模式
1、 添加observer
2、 参数改变后,通过注册的observer修改内存中的参数值
参考资料
http://mingxinglai.com/cn/2014/10/design-pattern/
http://blog.youkuaiyun.com/zhengzhb/article/details/7331369