首页 > 学院 > 开发设计 > 正文

库与设计模式

2019-11-09 17:39:06
字体:
来源:转载
供稿:网友

库是一组代码模块,它按照可复用的方式组织而成。代码库中保存的是有用、可复用的、编译后的代码,这样,程序员不需要处理代码库的任何源代码都能够利用它的功能。 当复用来自库中的任何模块时,其工作由链接器在链接编译阶段完成,即在编译之后的程序代码和标准库中的库二进制文件进行链接,在程序中调用库函数时将直接跳到库中对应的代码并执行。 库是一个文件,它包含了一个或者多个编译后的文件(称为目标文件),并对其进行索引,以便链接器能够更容易地找到对应符号(例如:类名称、类成员、函数、变量等)以及它们的定义。

建立并复用库

如果项目工程依赖于某个外部库,则必须编辑这个工程文件,指定库的位置和名称并将它的值赋予 INCLUDEPATH 和 LIBS 。

组织库:依赖性管理

如果一个程序元素复用了另外一个程序元素,则它们之间就存在依赖性。也就是说,构建、使用或者测试这个元素时,就要保证另一个元素存在且是正确的。 如果编译 PRogElement2.cpp 时必须包含 ProgElement1.h ,则称这种依赖性为编译时依赖;如果目标文件 ProgElement2.o 包含 ProgElement1.o 中定义的符号,则称其为链接时依赖。 代码复用,这是一个有价值且重要的目标,但总会产生依赖。当设计类和库时,需要确保尽可能地减少不必要的或者无意的依赖性,因为它们会延长编译时间,降低类和库的可复用性。每一次用 #include 指令包含头文件时,都会带入这个头文件中所包含的其他头文件,这样它们之间的依赖性就会相应的增多。

框架与组件

框架是一个(通常非常大)通用(或针对特定领域的)类与约定的集合,其目的是提高设计的一致性。框架经常被用来创建图形化应用、数据库应用或者其它复杂的软件。如同底层驱动中的机制和策略。 框架一般都具有文档丰富的公共 API 。API 是库中公共函数、类和接口的描述。为了实现框架,可以采用设计模式。 Qt 是许多开源的面向对象框架中的一种,它提供一组可复用的组件(即每个平台下都有特定的工具集调用),用于创建跨平台的应用。而利用 Qt 这样的多平台框架,就可以从其他人的创造性工作中获得大量的好处。

设计模式

设计模式是一种高度抽象的模板,可以将它们应用到不同类型的设计问题上。设计模式是“在特定环境下用于解决某类设计问题中类与对象间通信关系的描述”

比如:

Qt 中的序列化器模式:QTextStream 和 QDataStream

序列化器是一种只负责读取或写入对象的对象模板。 QTextStream 序列化器用于读写人类可以直观理解的文本文件。而 QDataStream 序列化器用于读写结构化的二进制数据。(比如说:可以将一个结构体完整的写入到文件,且轻易读出),也用于网络数据的传输。 下面一个实例展现了 QTextStream 和 QDataStream 的方面,即显示了序列化器模式在处理对象存储时的优势。

//MeataDataValue 代表的而是一首歌曲的属性class MetaDataValue {public: friend QTextStream& Operator<< (QTextStream& os, const MetaDataValue& mdv); friend QTextStream& operator>> (QTextStream& is, const MetaDataValue& mdv); friend QDataStream& operator<< (QDataStream& os, const MetaDataValue& mdv); friend QDataStream& operator>> (QDataStream& is, const MetaDataValue& mdv); friend bool operator== (const MetaDataValue&, const MetaDataValue&); virtual QString fileName()const; virtual QString genre()const; virtual QString artist()const; virtual QString trackTitle()const; virtual QString trackNumber()const;protected: bool m_isNull; QUrl m_Url; QString m_TrackNumber; QString m_TractTitle; QString m_Comment; QString m_Genrs; QString m_Artist; QTime m_TrackTime; QString m_AlbumTitle; QImage m_Image;};using namespace std;//写入(插入)数据到流中QTextStream& operator<< (QTextStream& os, const MetaDataValue& mdv){ QStringList sl; s. << mdv.m_Url.toString() << mdv.trackTitle() << mdv.artist() ; os << sl.join("/t") << "/n";//以自定义的格式,插入数据到流中 return os;}//序列化器,使用一个序列化流,流中可以保持各式各样的类型,int,QString,QTime 。。。//重写插入运算符和提取运算符。来操作一条流,效率,代码整洁度远高于操作对象中的单个数据。//从流中读取(提取)数据QTextStream& operator>> (QTextStream& is, MetaDataValue& mdv) { QString line = is.readLine(); QStringList fields = line.split("/t");//以自定义的格式提取数据 while (fields.size() < 9) { //如果长度小于9则用填充的方式来避免 非法 的内存操作。 fields << ""; } mdv.m_isNull = false; mdv.m_Url.setUrl(QUrl::fromUserInput(fields[0])); //从流中取出数据,然后定向到内存变量中 ; ; ; //代表省略。。。内容为:一系列成员变量的赋值。 return is;//此次只读了一行数据}QDataStream& operator<< (QDataStream& os, const MetaDataValue& mdv) { os << mdv.m_Url << mdv.trackTitle() << mdv.m_Image; ;;;; //此次,提取数据,DataStream和TextStream的区别也在于此,DataStream存的是二进制流,故流中可以是int,QTime,QStringStream等不同类型的数据。而TextStream中只能存的是字符串,QString return os;}QDataStream& operator>> (QDataStream& is, MetaDataValue& mdv) { is >> mdv.m_Url >> mdv.m_TrackTime >> mdv.m_Artist >> mdv.m_AlbumTitle;;;; //由于二进制流的特殊之处,成员变量直接对号入座。 return is;}

反模式

当然除了以上好的设计模式外,还有一些没有效果,低效率的编程实践被称为反模式 例如:

软件设计反模式 接口膨胀: 接口的功能强大而复杂,以至于难于复用面对对象设计反模式 循环依赖:在对象或者软件模块之间引入了不必要的直接或间接的依赖“上帝”对象:指拥有太多属性或太多责任的对象。比如:将模型和视图的代码组合在同一个类中编程反模式 魔幻数据:算法中包含了未解释的数字魔幻字符串:代码中包含直接的字符串作为事件类型进行比较方法学反模式 复制——粘贴编程:复制并修改已有的代码,而不是创建更通用的解决方案一切从头开始:不采用已有的解决方案,而是采用(执行起来表现要差很多)定制的解决方案
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表