【问题标题】:Tips on refactoring unstructured repetitive code into reusable components将非结构化重复代码重构为可重用组件的技巧
【发布时间】:2011-01-20 00:00:39
【问题描述】:

我已经搜索和搜索,但无法获得任何相关答案。希望有人可以提供帮助。

我开始编写类作为一种单元保存数据和另一个实用程序类来填充数据库中的类。好吧,对于一个小型代码库来说,这似乎不是什么大问题,但期待我成长为一个对面向对象设计和开发有扎实掌握的有能力的开发人员,我需要把它发展成一个合适的设计

让我们从初始类开始

public class Foo
{
   public int FooID {get;set;}
   public string FooName {get;set;}
   public string FooDescription {get;set;}
}

public class NotRelatedToFoo
{
   public int SomeID {get;set;}
   public string SomeName {get;set;}
   public string SomeDescription {get;set;}
}


public class Util
{
   public Util(){} 

   public List<NotRelatedToFoo> GetNotRelatedToFoos(string SomeName)
   {
     .... DB Code to return Data from DB 

     List<NotRelatedToFoo> notfoos = new List<NotRelatedToFoo>()
     (select * from NotRelatedToFoo where SomeName like @SomeName)
     foreach var item in db
     {
       NotRelatedToFoo notfoo = new NotRelatedToFoo ();
       notfoo.SomeID = item.SomeID;
       notfoo.SomeName = item.SomeName
       notfoo.SomeDescription = item.SomeDescription 
       notfoos.Add(notfoo);
      }
      return notfoos ;
   }

}

我的问题是,从这种设计中前进的最佳方式是什么。

编辑 目前 Util 类是一团糟,我需要建议如何按照结构化设计提取和分组功能

这是行不通的,或者可以吗

public class Foo
{
   public int FooID {get;set;}
   public string FooName {get;set;}
   public string FooDescription {get;set;}

   public List<Foo> GetFoos(string FooName)
   {
     .... DB Code to return Data from DB 

     List<Foo> foos = new List<Foo>()
     (select * from foo where FooName like @FooName)
     foreach var item in db
     {
       Foo foo = new Foo();
       foo.FooID = item.FoodID;
       foo.FooName = item.FooName
       foo.FooDescription = item.FooDescription 
       foos.Add(foo);
      }
      return foos;
   }
}

谢谢

【问题讨论】:

  • 这个问题应该为@AntiPatternMax 赢得“最佳标题”徽章。 :)
  • 请将您的问题标题编辑为合理的内容...
  • 这个标题倒是挺不错的,但还是和问题没太大关系
  • 也许您因为没有提出相关问题而无法获得相关答案?

标签: c# design-patterns


【解决方案1】:

我的问题是从这个设计中前进的最佳方式是什么。

名为UtilManager 的类或者你有什么通常是设计的味道。您应该能够描述类正在做什么(它应该有一个单一的职责),并且应该是类的名称。如果你必须使用通用的、模糊的、包罗万象的术语来描述类在做什么,那么你做错了,需要重新设计。

您的Util 班级做得太多了。它从数据库中获取两种不同类型的数据。通过以这种方式设计您的类,您将自己设置为违反开放/封闭原则(每次向模型添加新类型时,您都必须修改此类)。

至少,您需要单独的类才能从数据库中获取Foos 和NotRelatedToFoos。怎么样

abstract class Repository<T> {
     IEnumerable<T> GetAll();
}

abstract class SqlRepository<T> : Repository<T> {
    protected readonly SqlConnection connection;
    public SqlRepository(SqlConnection connection) {
        this.connection = connection;
    }
}

class FooRepository : SqlRepository<T> {

    public FooRepository(SqlConnection connection) : base(connection) { }

    public IEnumerable<T> GetAll() {
    }
}

等等。真正令人讨厌的是,您甚至可以将大量重复的水合对象代码从 IDataReader 提升到一个公共类中(提示:第一个版本将使用反射)。

除此之外,阅读SOLID。如果您真的想深入了解它,请尝试企业应用程序架构模式 (Fowler) 和设计模式(Gamma 等人)

【讨论】:

  • +1。我希望所有让我在同一个程序中使用多个完全不相关的Manager 类的库作者都在阅读。
  • 我喜欢这个,如果您能扩展您提供的代码示例,我将不胜感激
  • 更好的是,获得一个像 NHibernate 这样的 ORM,这样您就可以更多地处理 您的 应用程序中的对象(而更少地处理您的基础设施中所需的常见对象)。
  • @Berryl:虽然您的评论是正确的(每个人都应该使用 ORM),但切换到 ORM 并没有帮助解决 OP 试图对 OOP 不感到困惑的事实。
【解决方案2】:

访问数据库的常用方法是通过数据访问对象。 http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

不知道你是否还有其他用于持久化、更新或删除数据的类,但我通常通过 DAO 进行 CRUD 操作。

【讨论】:

    【解决方案3】:

    您的 Util 类负责许多事情(正如 Jason 之前指出的那样)。

    看起来,在它的关键点上,Util 正试图成为您的 FooUnrelatedToFoo 对象的存储库。

    我个人会考虑将其抽象为一些继承结构并引入泛型。

    如果您要创建大量以重复和基于约定的方式映射到数据库表的 POCO 对象,请考虑使用带有 FluentNHibernate 映射的 NHibernate 等 ORM。

    【讨论】:

    • 谢谢,我使用过 Linq to SQL 和 Subsonic,但我需要知道这一切是如何工作的。我认为很多开发人员都知道如何使用这些不错的插件,但不知道如何自己实现。
    • '但不知道如何自己实现它' - 我同意。我对 NHibernate 的工作原理有一个模糊的概念,但没有详细说明,而且我暂时不会认为我可以自己实现它。但这对我来说很好,我坚持我的编织。您是否真的需要了解它的工作原理,达到可以自己实现的详细程度?如果您着手真正了解您使用的所有东西,那么您充其量只能达到平庸。不要重新发明轮子,相信并信任全世界数百名其他开发人员使用的 3rd 方组件。
    猜你喜欢
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 2012-06-17
    相关资源
    最近更新 更多