【问题标题】:Best practices for managing several specialized versions of one app管理一个应用的多个专业版本的最佳实践
【发布时间】:2008-10-29 01:45:25
【问题描述】:

我有一个有很多面孔的 Web 应用程序,到目前为止,我已经通过创建主题来实现它。主题是一组用于通用后端的 html、css 和图像。

事情是这样布置的:

code/
themes/theme1
themes/theme2

Web 应用程序的每个实例都有一个配置文件,说明应该使用哪个主题。示例:

theme="theme1"

现在新的业务规则要求我对某些主题进行更改,这些更改无法通过简单地更改 html/css/images 来实现,并且需要更改后端。在某些情况下,这些更改需要应用于一组主题。

我想知道如何最好地将它放在磁盘上,以及如何在代码中处理它。我敢肯定其他人一定遇到过这个问题。

一个想法是:

code/common
code/theme1
code/theme2
themes/theme1
themes/theme2

然后让我的通用代码设置include_path,以便首先搜索code/theme1,然后搜索code/common

然后如果我想专门说theme2LogoutPage 类,我可以简单地将页面从code/common 复制到code/theme2 下的同一路径,它会选择专门的版本。

这个想法的一个问题是会有多个具有相同名称的类。虽然理论上它们永远不会包含在同一个执行中,但我无法扩展原始基类。

那么,如果我要为基类起一个唯一的名称呢?例如Theme1LogoutPage extends LogoutPage。我可以预见的一个问题是当一些通用代码(比如调度程序)引用LogoutPage 时。我可以向调度程序添加条件,但我想知道是否有更透明的方式来处理这个问题?

我能想到的另一个选择是为每个主题维护单独的分支,但我认为这可能需要很多工作。

最后要考虑的一点是,功能可能源自一个主题,然后需要合并到通用代码库中。

非常感谢任何输入。如果有什么不同,那就是 LAMP 环境。

【问题讨论】:

  • 你为什么要否决我的问题?这里有一百万零一个关于你喂你的狗吃什么类型的狗粮的民意调查。这是一个有效的设计问题。如果它不适用于您,为什么不直接忽略它?

标签: php oop inheritance directory-structure


【解决方案1】:

我没有具体的建议。但是,我强烈建议不要走捷径...使用您会觉得合适的解决方案来添加第三个主题或在明年更改某些内容。
重复是可维护性的敌人。

【讨论】:

  • 感谢 cmets 合气道。我同意你关于重复的说法。
【解决方案2】:

我将研究使用策略模式作为在网站的不同版本中实现不同功能的一种方式。拥有一个工厂,它接受您的配置并基于它提供适当的代码策略。每个策略都可以实现一些通用接口,以便从调用类的角度来看它们是可互换的。这将隔离您的更改以实现对 Factory 类、Configuration 类以及您需要实现以进行更改的任何新策略类的新策略。您可以对需要在不同版本之间有所不同的任何用户控件执行相同(或类似)操作。

我会用伪代码来说明(可能看起来有点像 C#)

public interface ILogoutStrategy
{
   void Logout();
}

public abstract class AbstractLogoutStrategy : ILogoutStrategy
{
   public virtual void Logout()
   {
      // kill the sesssion
   }
}

public class SingleSiteLogoutStrategy : AbstractLogoutStrategy
{
   public void Logout()
   {
      base.Logout();
      // redirect somewhere
   }
}

public class CentralAuthenticationSystemLogoutStrategy : AbstractLogoutStrategy
{
   public void Logout()
   {
      base.Logout();
      // send a logout request to the CAS
      // redirect somewhere
   }
}

public static class StrategyFactory
{
   public ILogoutStrategy GetLogoutStrategy(Configuration config)
   {
      switch (config.Mode)
      {
         case Mode.CAS:
            return new CentralAuthenticationSystemLogoutStrategy();
            break;
         default:
         case Mode.SingleSite:
           return new SingleSiteLogoutStrategy();
           break;

      }
   }
}

示例用法:

ILogoutStrategy logoutStrategy = StrategyFactory.GetLogoutStrategy( config );
logoutStrategy.Logout();

【讨论】:

  • 感谢您的详细解答!所以你的建议是应该有一个代码库。代码不应基于预期站点而专门化,而应基于其功能。然后配置文件(每个站点)将说明该站点向用户提供了哪些功能。是这样吗?
【解决方案3】:

您是否使用母版页?如果您需要不同的布局和 UI 内容,您可以为每个实例设置一组不同的母版页。如果您需要自定义行为,那么您可能需要研究依赖注入。 Spring.NET等

【讨论】:

  • 您已编辑问题以表明您的环境不是 ASP.NET。我是根据您在 ASP.NET 中的假设来回答的。对不起。
【解决方案4】:

你需要的是模板。

然后您可以将代码与演示文稿分开。

我强烈推荐 smarty 模板。还有 PEAR template_it。

http://www.smarty.net/

这也使您的代码更易于维护。目的是在你的 php 中没有 html,并且在你的 html 中没有 php。

那么您需要做的就是更改用于每个主题的 html 模板。或模板文件夹。

【讨论】:

    【解决方案5】:

    您可以: /常见/代码

    并且: /站点名称/代码

    /common/code 中的所有文件都是抽象类。 对于 /common/code 中的每个文件,只需在 /sitename/code 中创建一个对应的非抽象类文件,该文件继承自 /common/code 中的抽象类。

    这样你只需要在 /sitename/code 中实现 CHANGES 其他一切都是只存在于 /common/code 中的核心功能

    这里要做的重要事情是确保您只向抽象类添加 public 方法。这样,所有站点都可以使用这些方法,并且可以相同地处理/处理来自所有站点的类。

    【讨论】:

      【解决方案6】:

      我愿意:

      [主题名称]/[子文件夹] 默认/普通 默认/普通/html 默认/普通/css 红色/代码 红色/普通 红色/普通/html 红色/普通/css 红色/代码 绿色/普通 绿色/普通/html

      因此,如果代码或任何其他组件不存在,它将回退到默认值。

      但实际上我会在 svn 中对网站进行分支,所以如果它发展了通用代码,我可以合并它等等。请参阅 Subversion:http://subversion.tigris.org/

      【讨论】:

        猜你喜欢
        • 2012-01-12
        • 2011-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-01
        • 1970-01-01
        • 2015-10-28
        • 2023-04-08
        相关资源
        最近更新 更多