代码之家  ›  专栏  ›  技术社区  ›  nicolaskruchten

一些可重用代码的体系结构

  •  2
  • nicolaskruchten  · 技术社区  · 16 年前

    我正在编写一些小型、简单的应用程序,它们共享一个共同的结构,并且需要以相同的方式做一些相同的事情(例如,日志记录、数据库连接设置、环境设置),我正在寻找构建可重用组件的一些建议。代码是用一种强静态类型语言编写的(例如Java或C#,我必须用这两种语言解决这个问题)。现在我有了这个:

    abstract class EmptyApp //this is the reusable bit
    {
       //various useful fields: loggers, db connections
    
       abstract function body()
       function run()
       {
            //do setup
            this.body()
            //do cleanup
       }
    }
    
    class theApp extends EmptyApp //this is a given app
    {
       function body()
       {
            //do stuff using some fields from EmptyApp
       }
    
       function main()
       {
            theApp app = new theApp()
            app.run()
       }
     }
    

    有更好的办法吗?也许如下?我在权衡取舍方面有困难。。。

    abstract class EmptyApp
    {
         //various fields
    }
    
    class ReusableBits
    {
        static function doSetup(EmptyApp theApp)
    
        static function doCleanup(EmptyApp theApp)
    }
    
    class theApp extends EmptyApp
    {
        function main()
        {
             ReusableBits.doSetup(this);
             //do stuff using some fields from EmptyApp
             ReusableBits.doCleanup(this);
        }
    }
    

    3 回复  |  直到 16 年前
        1
  •  4
  •   Aaron    16 年前

    因此,对于您的示例,我将有多个ReusableBits类,每个类做一件事情,每个应用程序在需要时使用。

    这允许每个应用程序重用框架中与特定应用程序相关的部分,而不必被迫接受所有内容,从而使单个应用程序更自由。如果将来有一些应用程序不完全符合您现在所考虑的结构,那么通过继承重用有时会变得非常受限。

    如果您将框架分解为单独的实用程序,您还将发现单元测试和测试驱动开发更容易。

        2
  •  0
  •   Brian Agnew    16 年前

    为什么不对可定制代码进行框架调用呢?因此,您的客户机创建了一些对象,并将其注入到框架中。框架初始化、调用 setup() 等等,然后调用客户的代码。在完成时(甚至在抛出异常之后),框架将调用 cleanup() 和出口。

    因此,您的客户机只需实现一个接口,如(在Java中)

    public interface ClientCode {
    
        void runClientStuff(); // for the sake of argument
    }
    

    框架代码配置了此的实现,并调用 runClientStuff()

    所以你不知道 得到 从应用程序框架,但只提供符合特定契约的类。您可以在运行时配置应用程序设置(例如,客户端将为应用程序提供什么类),因为您不是从应用程序派生的,因此您的依赖关系不是静态的。

    上面的接口可以扩展为具有多个方法,并且应用程序可以在生命周期的不同阶段调用所需的方法(例如,提供特定于客户端的设置/清理),但这是功能爬行的一个示例:-)

        3
  •  0
  •   kay.one    16 年前

    请记住,如果继承的所有对象都由于它们的相似性而重用代码,那么继承才是一个好的选择。或者如果你希望呼叫者能够在同一个裂变中与他们互动。

    这就是我如何在C#中重新编写您的示例应用程序的方法。

    abstract class BaseClass
    {
        string field1 = "Hello World";
        string field2 = "Goodbye World";
    
        public void Start()
        {
            Console.WriteLine("Starting.");
            Setup();
            CustomWork();
            Cleanup();
        }
    
        public virtual void Setup()
        {Console.WriteLine("Doing Base Setup.");}
    
        public virtual void Cleanup()
        {Console.WriteLine("Doing Base Cleanup.");}
    
        public abstract void CustomWork();
    }
    
    class MyClass : BaseClass
    {
        public override void CustomWork()
        {Console.WriteLine("Doing Custome work.");}
    
        public override void Cleanup()
        {
            Console.WriteLine("Doing Custom Cleanup");
            //You can skip the next line if you want to replace the
            //cleanup code rather than extending it
            base.Cleanup();
        }
    
    }
    
    void Main()
    {
        MyClass worker = new MyClass();
        worker.Start();
    }