2011-07-22 70 views
1

說我有一個汽車類:單一職責原則 - 從文件加載列表?

class Car 
{ 
    string GetMake() 
    string GetModel() 
    int GetYear() 
} 

而且我持有的汽車名單的自定義CarService類:

class CarService 
{ 
    void AddCar(Car car) 
    void RemoveCar(Car car) 
    List<Car> GetCars() 
    ... other methods removed for clarity... 
} 

現在我想從一個文件加載車名單CarService類。我的舊OOP直覺就是將它作爲CarService類中的LoadFromFile()方法。然而,當我正在學習SRP和可測試性時,我不太確定。

遵循單一責任原則,設計此方法的正確方法是什麼?我應該有CarLoader類嗎?

UPDATE

我認爲解決的辦法應該是在各種各樣的語言一樣,但我會用C++。如果我使用C#,Java或python,我的問題將會完全相同。

回答

1

根據你要實現這個的語言,我會說load_carservice函數或等效的靜態方法就足夠了。

靜態方法解決方案可能被認爲違反了SRP,因爲序列化格式可能會改變,而其餘的類保持不變。這就是爲什麼我從來不會用強迫我把所有東西放在課堂上的語言編程的原因之一。如果你的語言強迫你這樣做,並且你想嚴格遵守SRP,那麼就需要額外的課程。

+1

那麼這是不可能的,我將使用一個靜態的方法,因爲我從可測試性的角度來看這些是邪惡的。我不一定要嚴格遵守SRP,但如果它通常被認爲是更好的設計,那麼我可能會選擇SRP解決方案。 – User

0

你可能應該不是有一個CarLoader類。至少根據你所顯示的內容,你的CarService類別看起來也不是很有用。至少從目前來看,它看起來像(如果它做了任何有用的事情)你的CarService基本上是試圖建立一個List頂部set。我想我會寫的代碼是這樣的:

class Car { 
// ... 
    friend std::istream &operator>>(std::istream &is, std::Car &c) { 
     return is >> c.model >> c.year >> c.color; 
    } 
    friend std::ostream &operator<<(std::ostream &os, std::Car const &c) { 
     return os << c.model << "\t" << c.year << "\t" << c.color; 
}; 

std::set<Car> cars; 

std::ifstream car_file("cars.txt"); 

// read data from the file: 
std::copy(std::istream_iterator<Car>(car_file), 
      std::istream_iterator<Car>(), 
      std::inserter(cars)); 

std::set已經知道如何添加和刪除項目......

+0

對不起CarService確實有其他功能,我不想簡化。您的解決方案很聰明,很好地利用了C++語言。很可能我的CarService類會被重構得更好,但是我更關心在SRP範例下從文件加載對象的一般情況。在你的例子中,如果我想從兩種不同的文件類型加載? – User

+0

@用戶:這取決於。它們有什麼不同(以及爲什麼?)根據具體情況,使用代理類提供來自不同來源的轉換可能很有用,但很難對這樣的一般問題給出非常具體的建議。 –