决定如何重构具有许多方法的类

时间:2015-08-13 06:59:16

标签: language-agnostic refactoring

我注意到,与我倾向于在线阅读的代码相比,我的课程往往更大/更长。以下代码仅作为示例,但我对思考方法以及如何解决问题更感兴趣。

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

所以我有一个带有以下声明的Backend类。我正在使用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()
}

1 个答案:

答案 0 :(得分:0)

关注点分离

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

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

  1. 维护一组对象(您的&#34;本地数据库&#34;)
  2. 读取/写入云服务器
  3. 将云服务器数据转换为模型类对象
  4. 在两个方向上保持本地数据库与云数据库同步。
  5. 定义业务对象模型(用户,地点,子优先级等)。
  6. 协调以上所有内容。
  7. 如果我实现这一点,我会将1-4分为不同的类。对于#5,我将模型移到Backend之外,因此它们是独立的类。

    1. 维护一组对象(您的&#34;本地数据库&#34;) 数据存储属于自己的类。对于所有对象类型,这已经非常复杂了。
      1. 读取/写入云服务器 访问外部资源的任何代码都属于它自己的类,它只进行数据访问。理想情况下,此类应首先定义为接口,调用者应仅通过接口调用它。这样可以更容易地交换提供程序,也可以帮助进行测试(您可以在运行时为测试提供不同的DAL实现)并加强关注点的分离。
        1. 将云服务器数据转换为模型类对象 这可以在DAL中或在中间层中完成。要下载云数据,您可以将方法添加到集合类中,如

          LocalDatabase.Users.Update(列出<User&gt; usersFromCloud){}

          1. 保持本地数据库与云数据库同步。 位于Backend,云DAL和本地数据库之间的中间类可以自动同步&#34;只要它知道一方的数据是陈旧的。或者,这可以移动到实用程序类。哪个最好取决于您的要求。
            1. 定义业务对象模型(用户,地点,子优先级等)。 后端之外的代码使用这些模型,因此它们属于后端定义之外。
              1. 协调以上所有内容。 当您取出上面列出的所有内容时,剩下的内容将是对新类进行所有工作的一系列方法调用。您的后端课程将更多地成为将工作委派给相应课程的协调员。
              2. 我做的其他事情

                使用非静态类。如果要使用一个全局对象来提供对后端的访问,则可以使用单例。 (Google&#34; C#singleton&#34;例如。)。这样可以更轻松地测试代码(通过交换存储在单例中的内容,例如使用从文本文件返回值的虚拟实现),如果有必要,可以更轻松地切换到非全局实现。