C++ 中的 OOD:只有一个方法的类?

Posted

技术标签:

【中文标题】C++ 中的 OOD:只有一个方法的类?【英文标题】:OOD in C++: Having a class with just one method? 【发布时间】:2015-04-21 04:33:38 【问题描述】:

我正在用 C++ 编写一个程序,并考虑到面向对象的设计,它将二手车记录保存在数据库中。我有一个按年份对汽车进行排序的函数,但该函数应该是它自己的类中的方法、汽车类中的方法,还是只是任何类之外的函数?我们被教导在面向对象设计中,一切都应该在它自己的类中,并且每个类应该只有一个责任,所以我倾向于将函数作为方法放在它自己的类中,但这似乎没有必要。我该怎么办?

【问题讨论】:

另外,只有方法的类是否需要构造函数,即使该类不包含数据成员? 您为汽车使用什么样的容器(例如数组)?您是否熟悉标准库容器(例如vector<Car>)? @beta 它将是汽车的数组,是的。抱歉,我对此并不熟悉,我对 C++ 中的类和面向对象设计的知识非常有限 @beta 我只被教导使用“使用命名空间标准”,如果这适用于你所说的 我要给你的最好的建议是不要再把 OOP/OOD 看作是近乎宗教层面的神圣事物。设计是由很多因素驱动的,最重要的是一个团队的需求,他们必须顺利合作。没有 OO 方法可以证明问题的一个分区比另一个分区更正确。此外,OOP 并不意味着任何东西都必须在一个类中。类在有用时是抽象。但不是“必须”。没有什么可以例如对一个方法说:void SortByAge( CarList& cars );CarList SortByAge( const CarList&cars); 【参考方案1】:

它本身应该是一个函数,而不是任何类的成员。像这样的:

void sortCars(Car * lot, unsigned int numCars)
  ...

将它包装在没有其他成员的类中是没有意义的;这样做不会解决任何问题,也不会变得更容易。

让它成为Car 的成员是没有意义的,这样做会让它访问它不需要的类的私有成员,这是自找麻烦。

“一切都应该属于自己的类别”是一个粗略的指导方针,更适用于名词 (Car) 而不是动词 (sortCars)。

【讨论】:

【参考方案2】:

尽管我更喜欢使用一个简单的函数来完成这项工作并将其放在某个命名空间中,例如

namespace CarUtils 
    void sort(Car *carsArr, const size_t & arrSize) 
        // code ...
     
;

但是,随着您将了解更多诸如 STL 之类的知识以及诸如 algorithmsvectors 之类的功能,您会发现 sort 算法已内置。

现在您只需提供您的comparison function-objects

namespace CarUtils   // i would still put things in namespace :)
       struct SortByMileage 
              bool operator()(const Car & c1, const Car & c2) 
                  return c1.mileage < c2.mileage;
              
       ;

       struct SortByYear 
              bool operator()(const Car & c1, const Car & c2) 
                  return c1.purchaseDate.year < c2.purchaseDate.year;
              
       ;
;

然后在你的代码中:

// #include <algorithm>  // include this file.
std::sort(cars, cars + sizeOfCarArr, CarUtils::SortByMileage());
// and to sort by year
std::sort(cars, cars + sizeOfCarArr, CarUtils::SortByYear());

这种方法更好,因为老实说,您不应该为不同类型的排序(如按里程或按容量等)一次又一次地编写排序函数。

但是.. 再次回到我们只在需要函数的地方使用函数的理念.. 我们可以使用 lambdas(C++11 特性):)

std::sort(cars, cars + sizeOfCarArr, [](const Car & c1, const Car & c2) 
       return c1.mileage < c2.mileage;
);

std::sort(cars, cars + sizeOfCarArr, [](const Car & c1, const Car & c2) 
       return c1.purchaseDate.year < c2.purchaseDate.year;
);

要使用 C++11,您需要将 -std=c++11 传递给编译器。

【讨论】:

【参考方案3】:

正如@meet 所说,尽量避免使用全局函数。另外,我认为确定数据库与汽车的关系类型很重要。

在我看来,例如,一辆二手车具有-a(与 is-a 相对,后者会进入继承)数据库,因此,它可以作为单独的函数而不是它自己的类来实现!

【讨论】:

汽车怎么能has a数据库? 因为数据库是汽车类的属性?您没有没有任何汽车的二手车数据库。 数据库将包含汽车信息,如年龄等。这个年龄将是汽车的成员/属性。类可以包含访问该属性的方法。但对这个属性做任何事情(如(排序))不是 Car 的属性。它不应该是类的一部分。

以上是关于C++ 中的 OOD:只有一个方法的类?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中的OOA.OOD.OOP有啥区别?

学习笔记ABAP OOD设计模式 - 单例模式

如何在 C++ 中的类中递归调用函数方法?

如何找到存储在 C++ 向量中的对象的类方法?

单例模式之C++实现

面向对象接口和类的区别