【问题标题】:managing software editions管理软件版本
【发布时间】:2010-03-22 22:19:29
【问题描述】:

我计划从现有代码库中用 Java 创建一个软件的 3 个版本。最佳做法是什么?我应该为每个版本创建 3 个不同的项目吗?还有用于管理版本的工具吗?

【问题讨论】:

  • 它是什么类型的应用程序?这是桌面应用程序、Web 应用程序、可本地安装的 Intranet 应用程序吗?您可以提供的详细信息越多,答案就会越好。
  • 这是一个java应用程序,可以是基于web的或独立的(更轻的版本)。在tomcat上运行(基于web的版本),需要一个数据库

标签: java version


【解决方案1】:

我的第一个想法是尽可能保留单个代码库并使用某种标志进行切换。

如果不可能,我会尽量保持相同,让较大的项目使用较小的项目作为子项目,如果可能的话自动启用某些功能——例如,每个项目都可以有它自己的主,不同的构建可能只是调用设置标志以启用功能的不同主。

如果您的标志是最终的,它甚至应该避免将不必要的代码拉入您的项目。

最后,最坏的情况,Subversion 中的 3 个分支。

编辑:

您让我对此进行了更多思考,我认为我找到了更好的解决方案。

我想我会把它分成四个项目,将所有“常见”的东西合并到一个基础项目中,而不同的东西,我会分散到其他三个项目中——假设你有基础、演示、支付和商业项目..

这三者可能不同,您将有一个来自演示/支付/业务类之一的对象提供该功能。例如,如果付费版本有新的菜单项,则您的一个对象中可能有一个 getMenuItems。它将返回一个菜单树,您可以将其放置在菜单栏中。演示版的项目会更少。

这样你的“基础”永远不知道它运行的是哪个版本,它只使用对象。

为了获得这些物品,我需要一个工厂。工厂看起来像这样:

private String[] availablePackages={"business", "pay", "demo"};

public getMenuClass() {
    Class c;
    for(String package : availablePackages) {
        try {
            c=Class.forName("com.meh.myapp."+package+".MenuClass");
        } catch... {
            // No package by that name
        }
        if(c != null) {
            return c.newInstance();
        }
    }
    // Something went wrong, no instance found.

上升趋势是您应该先尝试实例化 com.meh.myapp.business.MenuClass,然后尝试 ...pay.MenuClass 最后 ...demo.MenuClass。

这应该允许您通过简单地发送不同的 jar 来更改您的配置——如果您决定只发送演示和主 jar,您将获得一个演示应用程序。通过运送支付罐,您将获得支付应用程序。

请注意,您很可能希望业务将大部分工作委托给“支付”,而“支付”将大量工作委托给“演示”,但演示对业务或支付一无所知,而“main”只知道其他三个反射性。

这将是一个很好的解决方案,因为不需要配置 - 事实上,您只需运送付费 jar 即可从演示升级到付费,主 jar 和演示 jar 可重复使用并保持在原处.

【讨论】:

  • 你有指向java编译最终标志的链接吗?快速搜索并没有给我带来太多信息。它如何丢弃未使用的代码?
  • 我的意思不是编译标志,我的意思是如果你有一个最终的变量,例如“private final boolean INCLUDE_CODE=false”任何受它保护的东西,例如:“if (INCLUDE_CODE ) myVar=new SpecialClass();"甚至不应该编译到代码中。它应该认识到它永远不可能是真的并优化它。如果这是引用 SpecialClass 的唯一地方,那么 SpecialClass 根本不应该被拉入您的项目中——但无论如何我可能已经想出了一个更好的解决方案,请重新阅读我的答案。
【解决方案2】:

理想的方法是将您的应用程序划分为“核心”、“附加内容”、“更多附加内容”并结合这些依赖项。不过,这可能需要大量工作,具体取决于您拥有的代码库。

如果您使用 SVN 进行源代码管理,您可以从现有代码库为每个版本创建 3 个分支。通常人们会尽量避免这种情况,因为例如如果您需要修复这些分支中的常见错误,则需要在其中一个分支中修复该错误,然后将其合并到其余分支。也许其他源存储库更好地处理这种情况,但对于 SVN,我想这是唯一的方法。

至于管理版本,我们使用 maven。如果您采用“核心”、“附加内容”、“更多附加内容”的方法,maven 可以提供帮助,因为它可以非常干净地跟踪每个组件的版本(使用 pom)。

编辑:比尔的建议可能是最实用的。如果您使用最终标志,是的,编译器应该丢弃无法访问的代码。

【讨论】: