【问题标题】:Design pattern for methods in another class另一个类中方法的设计模式
【发布时间】:2008-12-11 09:38:50
【问题描述】:

我正在寻找特定的设计模式。

例如,我有一个文章类 clsArticle。此类包含成员变量,如 Id、标题、作者、文章等。想象一下,我想在列表中显示所有文章。所以在某个地方我必须创建一个方法 getAllArticles()。由于 clsArticle 不负责获取所有文章,所以我必须将此方法放在另一个类 clsArticleFact(Fact 代表工厂)中。

有人知道这种模式的名称吗?这种工作方式是设计模式吗?

【问题讨论】:

    标签: design-patterns oop


    【解决方案1】:

    是的。这是正确的。

    它可以是 AbstractFactory 或 DataAccessObject。

    第一个是当你想让实现返回不同类型的文章时

    例如,假设您有一个条件,即文章的行为因平台而异。

    ArticleFactory.getAll(): Article[]
    

    将在每个平台返回正确的列表。

    实现可能是:

    WindowsArticleFactory
    

    OSXArticleFactory
    

    前者可用于抽象检索文章的地方:

    你可能有

    ArticleDao.getAll(): Article[]
    

    和实现:

    XmlArticleDao // Return a list of articles from an XML
    

    DatabaseArticleDao // return the list from the database.
    

    这里的重点是将创建(getAll())与使用(文章)解耦

    如果您的应用程序足够简单,您可以使用 factoryMethod。

     class Article { 
         static Article[] getAll() {
             // do whatever is neede here...
         }
     }
    

    我希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。我真的不明白。我正在用 C# 编程。我只有一种文章类型。
    • @Martijn: OT: 如果你用 C# 编程,你真的不应该为任何东西使用前缀(比如你的 clsArticle),你不应该缩写任何东西(比如你的 *Fact)。看看 .NET Framework 中的命名指南,这也将使任何回答您未来 C# 问题的人受益。
    • 这同样适用于任何 OO 语言。事实上,你不需要那么大的灵活性。最后一个选项(使用类方法)对你来说就足够了。但是,如果您希望将所有这些操作放在一个单独的类中,您仍然可以调用 ArticleFactory。这个概念保持不变
    【解决方案2】:

    您也可以使用 Rails ActiveRecord 模型类所采用的方法

    public class clsArticle
    {
      public static clsArticle[] findAll() { /*... */ }
    
      // the other regular code here;
    }
    
    // client code
    foreach(clsArticle obArticle in clsArticle.findAll())
    {
      list.add(clsArticle)
    }
    

    【讨论】:

    • 是的,这是我提到的第三个选项。这里真的不需要额外的灵活性。
    • 我不太同意上述言论,因为这个问题被标记为“设计模式”和“oo 设计”,我们并不(仅)对“最快的工作方式”感兴趣。
    【解决方案3】:

    好吧,为此创建一个静态类:

    public static class clsArticles
    {
        public static clsArticles[] GetAllArticles() { /* actual code */ }
    }
    

    【讨论】:

    • 因为目前该类的唯一目的是提供对静态方法的访问。
    • 谢谢。我还应该使用静态成员吗​​?保存文章?还是按 ID 获取文章?
    【解决方案4】:

    不要创建静态方法!

    您首先想到的应该是界面

    也许您可以编写类似(Java 中的示例)

    public interface ArticleService {
        Article[]  getAllArticles() throws ServiceException();
    }
    

    您需要对文章执行的所有其他操作也会进入此界面。将此类(DbArticleService、XmlArticleService、...)的具体实现注入到每个需要处理 Articles 的对象中。

    这样,正如其他发帖者所提到的,您可以获得解耦的代码和良好的关注点分离。

    但是无论你做什么,都不要把东西变成静态的。

    【讨论】:

    • 使用这种方式,那么我应该把SaveArticle(Article object)、GetArticleByID(int ArticleID)、DeleteArticleById(int ArticleID)等方法放在哪里?
    • 在 ArticleService 界面上。
    【解决方案5】:

    您所描述的并不是真正的模式,而是一种称为“关注点分离”的编程原则。

    根据您的描述,我强烈认为您遵循的是结构设计模式,而不是创建设计模式,因为编码关注点的分配是在创建共谋上讨论的。

    所以,我最好的猜测是,您所追求的模式可能是 Facade PatternGateways。将实体(您的 clsClass)与网关一起使用是很常见的。

    然而,我不一定鼓励将方法设为静态,但是从那时起,在业务逻辑测试期间就不能模拟这些方法。如果这些类型的方法形成应用程序的数据层,则您可能希望模拟这些返回数据访问对象的方法,因为当业务逻辑依赖于这些网关/门面时,您不希望访问数据库。

    public class clsClass
    {
        public int ID;
        public string title;
        public string author;
        public string article;
    }
    
    
    public class BookGateway
    {
        public List<clsClass> GetAllArticles()
        {
            var result = new List<clsClass>();
    
            // Add items here.
            // Can call database and populate each new clsClass
            // and add to result object.
    
            return result;
        }
    }
    

    【讨论】:

    • 感谢您的回复。我不明白最后一部分。 BookGateWay 类是我的业务逻辑。在我的例子中,这个类包含数据库类的一个对象。所以这是正确的吧?
    • 回复的最后一部分是给高级开发者的。尽早避免使用静态方法的原因。作为一般规则,只在严格需要的地方制作静态。 BookGateway 确实是业务逻辑,会调用数据库并用数据库值填充每个 clsClass。
    • 奥斯卡的反应不是你所追求的。使用网关并根据需要将所有新方法(...如 SaveArticle(Article object)、GetArticleByID(int ArticleID)、DeleteArticleById(int ArticleID)...)添加到网关。
    猜你喜欢
    • 1970-01-01
    • 2017-12-23
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 2019-07-29
    • 2013-06-04
    • 1970-01-01
    相关资源
    最近更新 更多