繁体   English   中英

静态类只包含静态方法的困境

[英]Dilemma of static class containg only static methods

所以我有这个映射两个酒店目录的任务; 两者都是csv文件。 我根据他们的职责创建了两个类:1。CatalogManager:处理目录的I / O操作。 2. CatalogMapper:处理两个目录的映射任务。

定义如下:

public static class CatalogManager
{
   public static List<Hotel> GetHotels(string filePath) { }
   public static void SaveHotels (List<Hotel> hotels, string filePath) { }
   public static void SaveMappedHotels (List<MappedHotel> hotels, string filePath) { }
   public static List<string> GetHotelChains(string filePath) { }
}

public static class CatalogMapper
{
   public static List<MappedHotel> MapCatalogs (List<Hotel> masterCatalog, List<Hotel> targetCatalog) { }

   public static FetchAddressGeoCodes (Hotel.Address address)
   { // fetch address's geocode using Google Maps API }

   public static string GetRelevantHotelChain (string hotelName)
   {
      List<string> chains = CatalogManager.GetChains();
      // find and return the chain corresponding to hotelName. 
   }
}

典型的映射操作可能类似于:

List<Hotel> masterCatalog = CatalogManager.GetHotels(masterFilePath);
List<Hotel> targetCatalog = CatalogManager.GetHotels(targetFilePath);
List<MappedHotel> mappedHotels = CatalogMapper.MapHotels(masterCatalog, targetCatalog);
CatalogManager.SaveMappedHotels(mappedHotels, mappedCatalogFilePath);

如代码所示,这两个类都是静态的。 虽然我发现它们正确且有效,但我仍然认为这种设计在OOP方面存在问题。 两个类都是静态的,这样很好吗? 我发现没有必要实例化它们。 此外,这个设计还有哪些缺陷? 我确信存在缺陷。 那些解决方案是什么?

另一种合理的方法是使CatalogManager成为使用文件名初始化的非静态类。 这将允许您部分地从内存中使用文件,并在需要时进行读取或写入。

不怕自由功能!

我发现CatalogMapper映射了一个Hotel.Address是可疑的。 要正确分解/封装,要么

  • CatalogMapper应该在非酒店专用Address

  • 或者,如果Hotel.Address以某种方式特殊于GeoCodes,那么Hotel.Address应该能够将自己映射到没有CatalogMapper的GeoCode。


通过评论的澄清,我想提出以下建议。 我不知道C#所以我会把它写成C ++。 我希望它翻译

struct Hotel {
    const Address & address () const;

    // I typedef EVERTYTHING :-)    
    typedef std :: list <std :: string> StringList;
    typedef std :: pair <Hotel, Hotel> Pair;
    typedef std :: list <Hotel> Container; // TODO implicit sharing?
    typedef std :: list <Pair> Mapping;

    // NB will be implemented in terms of std::istream operations below,
    // or whatever the C# equivalent is.
    // These could arguably live elsewhere.
    static Container load (const std :: string &);
    static Mapping load_mapping (const std :: string &);
    static void save (const std :: string &, const Container &);
    static void save_mapping (const std :: string &, const Mapping &);

    // No need for a "Manager" class for this.
    static StringList load_chain (const string & file_name);

private:
    static Hotel load (std :: istream &);
    void save (std :: ostream &) const;
};

// Global namespace, OK because of overloading. If there is some corresponding
// generic library function which merges pair-of-list into list-of-pair
// then we should be specialising/overloading that.
Hotel :: Mapping merge (const Hotel :: Container &, const Hotel :: Container &);

struct GeoCode {
   GeoCode (const Address &);
};

每当我看到一个名为“经理”的类时,如果它不是创建,拥有和控制对其他对象的访问的对象,那么它就会警告我们在名词王国中。 对象可以管理自己。 如果逻辑超出单个类的范围,您应该只有一个单独的逻辑类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM