【问题标题】:Deciding how to refactor a class having many methods决定如何重构具有许多方法的类
【发布时间】:2015-11-06 00:35:04
【问题描述】:

我注意到与我倾向于在线阅读的代码相比,我的课程往往更大/更长。下面的代码旨在作为示例,但我更感兴趣的是思考和解决问题的方式。

正如您将看到的那样,该类处理许多角色,我很想学习如何将其重构为其他类和示例,如果可能的话,提供实用的解决方案。关于如何解决这个问题的书籍/指南的链接会很棒。

所以我有一个带有以下声明的后端类。我正在使用 C#,但我认为我的问题涉及其他语言。

public static class Backend {
    //These classes are the equivalent classes of a cloud database tables
    //Using them to map the tables to objects in my app
    public class User{}
    public class Place{}
    public class SubPriority{}
    public class Question{}
    public class Parent{}
    public class Response{}
    public class SubParent{}

    //initialize the local and cloud databases
    public static async void init();

    //Add place to local database
    public static string AddPlace(string name, string buildingType)

    //Retrieve places from local database
    public static List<Place> RetrievePlaces()

    //Delete a place from local database
    public static bool DeletePlace(string placeID)

    public static string AddSubPriority(String name)
    public static List<SubPriority> RetrieveSubPriorities()
    public static bool DeleteSubPriority(string placeID, int ID)

    //Sync local db with cloud
    public static async Task<bool> SyncWithCloud()

    //Download SubParents from the cloud
    public static async Task<List<SubParent>> DownloadSubParents()

    //Retrieve SubParents from local
    public static List<SubParent> RetrieveSubParents(int parentid)
    ...
    ...
    ...
    //Similar methods for parents and questions



    //Handling login
    public static async Task<bool> Login(string userName, string pass)
    static async Task<bool> LoginOnline(string userName, string pass)
    static bool LoginOffline(string userName, string pass)

    //Check for internet connectivity
    static async Task<bool> isConnectedToInternet()
    static bool InternetAvailable()
}

【问题讨论】:

标签: language-agnostic refactoring


【解决方案1】:

关注点分离

将所有这些逻辑保留在一个类中的困难在于,更改一件事可能需要对整个类进行重大更改,这会产生错误。同样重要的是,当类承担单一角色时,更容易阅读和理解。可读的代码总是有更少的错误(根据我的经验)。

您的单个​​班级至少处理以下角色:

  1. 维护对象集合(您的“本地数据库”)
  2. 读取/写入云服务器
  3. 将云服务器数据转换为模型类对象
  4. 使本地数据库与云数据库在两个方向上保持同步。
  5. 定义您的业务对象模型(用户、地点、子优先级等)。
  6. 协调上述所有工作。

如果我要实现它,我会将 1-4 分成不同的类。对于 #5,我会将模型移到后端之外,因此它们是独立的类。


  1. 维护对象集合(您的“本地数据库”) 数据存储属于它自己的类。对于您所有的对象类型,这已经非常复杂了。

  1. 读取/写入云服务器 任何访问外部资源的代码都属于它自己的类,该类只进行数据访问。理想情况下,这个类应该首先定义为一个接口,调用者应该只通过接口调用它。这样可以更轻松地交换提供程序,还有助于测试(您可以在运行时提供不同的 DAL 实现进行测试)并加强关注点分离。

  1. 将云服务器数据转换为模型类对象 这可以在 DAL 或中间层中完成。对于下载云数据,您可以将方法添加到您的集合类中,例如

    LocalDatabase.Users.Update(List&lt;User> usersFromCloud){}


  1. 保持本地数据库与云数据库双向同步。 位于后端、云 DAL 和本地数据库之间的中间类可以在知道一侧的数据过时时“自动”同步。或者,可以将其移至实用程序类。哪个最好取决于您的要求。

  1. 定义您的业务对象模型(用户、地点、子优先级等)。 后端之外的代码正在使用这些模型,因此它们属于后端定义之外。

  1. 协调上述所有工作。 当您取出上面列出的所有内容时,剩下的将是对新类的一堆方法调用来完成所有工作。您的 Backend 类将更像是一个协调者,将工作委派给适当的类。

我会做不同的其他事情

使用非静态类。如果您打算使用一个全局对象来提供对后端的访问,您可以使用单例。 (例如,谷歌“C# 单例”。)。这将使您更容易测试您的代码(通过交换您存储在单例中的内容,例如使用从文本文件返回值的虚拟实现),并且在以后有必要时更容易切换到非全局实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-14
    • 1970-01-01
    • 2022-10-24
    • 2015-06-30
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多