一些可重用的代码结构
-
23-08-2019 - |
题
我写了一些共享一个共同的结构,需要做一些在相同的方式同样的事情(如日志记录,数据库连接设置,环境设置)小的,简单的应用程序和我在寻找一些建议在构建可重用的组件。该代码是写在一个强烈和静态类型语言(如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);
}
}
一个明显的代价是,与方案2中,“框架”不能完成该应用在try-catch块...
解决方案
我一直偏爱通过组合物(你的第二个选项)而不是继承(您的第一个选项)。
的再利用当在类之间,而不是代码重用的关系继承应仅被使用。
因此,对于你我就可以多ReusableBits类各做1两件事,每个应用程序化妆用的/需要的时候。
这使得每个应用程序重新使用是相关的,而无需被迫采取一切特定应用的框架的部分,允许个人申请更多的自由。再利用通过继承,如果你有在未来的某个应用程序不完全适合你今天心目中的结构有时会变得非常严格。
您还会发现单元测试和测试驱动开发容易得多,如果你打破你的框架成单独的工具。
其他提示
为什么不使框架调用到您的自定义代码?所以,你的客户端创建了一些对象,并将其注入的框架。该框架初始化,调用setup()
等,然后调用客户端的代码。完成后(或甚至抛出的异常之后),该框架然后调用cleanup()
并退出。
所以,你的客户端将只是实现一个接口,例如(在Java中)
public interface ClientCode {
void runClientStuff(); // for the sake of argument
}
和框架代码被配置成与这样的一个实施方式中,和在需要时调用runClientStuff()
。
所以你不要的导出的从应用程序框架,而只是提供符合特定合约的类。您可以在运行时配置web应用(例如什么类的客户端将提供给应用程序),因为你不是从应用程序导出等你的依赖也不是一成不变的。
上面的接口可以扩展到具有多个方法,以及应用程序可以调用在不同阶段所需的方法在生命周期中(例如,以提供客户特定的设置/清除),但是这是特征蠕变的例子: - )
记住,继承是只有一个很好的选择,如果被继承重用代码哆来它们的相似的所有对象。或者,如果你希望来电者可以在同一个裂变与他们互动。 如果我刚才提到的适用于您,然后根据我的经验,它始终是最好有共同的逻辑在你的基地/抽象类。
这是在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();
}