C++设计开发规范(5):扩展性设计规范
2007-07-24 18:18
162 查看
5. 扩展性设计规范
扩展的方式有很多种,常见的有基类/抽象类继承、接口实现、回调函数、虚函数重载、组合等。
l 推荐(相对)遵守敏捷开发(面向对象设计)基本原则:
a. SRP(单一职责原则)
就一个类而言,应该有仅只有一个引起它变化的原因。
b. OCP(开放封闭原则)
软件实体(类、模块、函数等)应该是可扩展的,但是不可修改
c. LSP(Liskov替换原则)
子类型必须能够替换掉它的基类型。
d. DIP(依赖倒置原则)
抽象不应该依赖于细节。细节应该依赖于抽象。
e. ISP(接口隔离原则)
不应该强迫客户依赖于他们不用的方法。接口属于客户,而不应该属于它们的类层次。
f. REP(重用发布等价原则)
重用的粒度就是发布的粒度。
g. CCP(共同封闭原则)
包中的所有类对于同一性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包的所有类产生影响,而对于其他的包则不产生影响。
h. CRP(共同重用原则)
一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
i. ADP(无环依赖原则)
在包的依赖关系图中不允许存在环。
j. SDP(稳定依赖原则)
朝着稳定的方向的进行依赖。
k. SAP(稳定抽象原则)
包的抽象程度应该和其稳定程度一致。
√ 要求在命名基类时,选择使用/不使用”Base”后缀,但不允许使用其它后缀。
class SpreadItemBase{…}//好
class SpreadItem{…}//好
class SpreadItemRoot{…}//不好
class SpreadItemTop{…}//不好
√ 要求使用public继承。
× 不要为派生子类提供可访问保护字段(除非别无选择)。
例如,
class EventHandler
{
protected:
object m_virtualView;//不好,会造成强耦合
}
× 不要使用友元类、友元函数(除非别无选择)
× 不要让一个类去实现与类的责任无关的接口,否则会造成类膨胀
例如,
interface IExportService{…}
interface ILayoutService{…}
interface ITypesetService{…}
//不好
class LayoutService : public IExport,
public ILayoutService,
public ITypesetService{…}
//推荐解决方案
class LayoutService : public ILayoutService {…}
class ExportService : public IExport {…}
class TypesetService : public ITypesetService {…}
× 不要使用接口,如果这个接口极不稳定
l 推荐使用回调函数来执行被依赖的实体(类、模块等) ,
相对虚函数重载和继承,这种扩展方式更灵活。但这种扩展方式的性能略微低于前两者。
例如,
class Layer
{
public:
typedef void (*LAYEREVENTHANDLER)( VOBJID32 oidSpreadItem);
///////////////////////////////////////////////////////////////////////////////////////////////
//public event
LAYEREVENTHANDLER SpreadItemDeleting;
LAYEREVENTHANDLER SpreadItemDeleted;
public:
void DeleteSpreadItem(VOBJID32 oidSpreadItem)
{
…
if (SpreadItemDeleting) SpreadItemDeleting(oidSpreadItem);
…
if (SpreadItemDeleted) SpreadItemDeleted (oidSpreadItem);
}
}
扩展的方式有很多种,常见的有基类/抽象类继承、接口实现、回调函数、虚函数重载、组合等。
l 推荐(相对)遵守敏捷开发(面向对象设计)基本原则:
a. SRP(单一职责原则)
就一个类而言,应该有仅只有一个引起它变化的原因。
b. OCP(开放封闭原则)
软件实体(类、模块、函数等)应该是可扩展的,但是不可修改
c. LSP(Liskov替换原则)
子类型必须能够替换掉它的基类型。
d. DIP(依赖倒置原则)
抽象不应该依赖于细节。细节应该依赖于抽象。
e. ISP(接口隔离原则)
不应该强迫客户依赖于他们不用的方法。接口属于客户,而不应该属于它们的类层次。
f. REP(重用发布等价原则)
重用的粒度就是发布的粒度。
g. CCP(共同封闭原则)
包中的所有类对于同一性质的变化应该是共同封闭的。一个变化若对一个包产生影响,则将对该包的所有类产生影响,而对于其他的包则不产生影响。
h. CRP(共同重用原则)
一个包中的所有类应该是共同重用的。如果重用了包中的一个类,那么就要重用包中的所有类。
i. ADP(无环依赖原则)
在包的依赖关系图中不允许存在环。
j. SDP(稳定依赖原则)
朝着稳定的方向的进行依赖。
k. SAP(稳定抽象原则)
包的抽象程度应该和其稳定程度一致。
√ 要求在命名基类时,选择使用/不使用”Base”后缀,但不允许使用其它后缀。
class SpreadItemBase{…}//好
class SpreadItem{…}//好
class SpreadItemRoot{…}//不好
class SpreadItemTop{…}//不好
√ 要求使用public继承。
× 不要为派生子类提供可访问保护字段(除非别无选择)。
例如,
class EventHandler
{
protected:
object m_virtualView;//不好,会造成强耦合
}
× 不要使用友元类、友元函数(除非别无选择)
× 不要让一个类去实现与类的责任无关的接口,否则会造成类膨胀
例如,
interface IExportService{…}
interface ILayoutService{…}
interface ITypesetService{…}
//不好
class LayoutService : public IExport,
public ILayoutService,
public ITypesetService{…}
//推荐解决方案
class LayoutService : public ILayoutService {…}
class ExportService : public IExport {…}
class TypesetService : public ITypesetService {…}
× 不要使用接口,如果这个接口极不稳定
l 推荐使用回调函数来执行被依赖的实体(类、模块等) ,
相对虚函数重载和继承,这种扩展方式更灵活。但这种扩展方式的性能略微低于前两者。
例如,
class Layer
{
public:
typedef void (*LAYEREVENTHANDLER)( VOBJID32 oidSpreadItem);
///////////////////////////////////////////////////////////////////////////////////////////////
//public event
LAYEREVENTHANDLER SpreadItemDeleting;
LAYEREVENTHANDLER SpreadItemDeleted;
public:
void DeleteSpreadItem(VOBJID32 oidSpreadItem)
{
…
if (SpreadItemDeleting) SpreadItemDeleting(oidSpreadItem);
…
if (SpreadItemDeleted) SpreadItemDeleted (oidSpreadItem);
}
}
相关文章推荐
- .NET 设计规范--.NET约定、惯用法与模式--6.为扩展性而设计
- C++设计开发规范(3):类型设计规范
- C++设计开发规范(4):成员设计规范
- Web UI 设计(网页设计)命名规范(转)
- Android/IOS APP界面设计之尺寸规范
- 最新Android & iOS设计尺寸规范
- SAP接口设计的扩展性考虑
- 移动端页面制作字号大小设定问题,设计稿文字字号规范,解决移动端大小屏适配问题
- iOS APP设计规范大全
- .NET代码设计简单规范
- 产品策划七:App界面交互设计规范
- UI设计规范整理一iOS字体和切图及规范
- 手机设计:红绿灯与设计规范
- Android & iOS设计尺寸规范
- 这份交互稿模板,可以让你的设计稿非常规范
- MYSQL数据库设计规范与原则
- 数据库设计规范(四)
- MySQL架构设计谈:从开发规范、选型、拆分到减压
- 如何开发设计更加符合规范的API