对于多个客户端使用的产品,其中不同的客户端要求用户界面和功能方面的不同自定义,如何适应这些更改而不会使代码与客户端特定代码混乱?
是否有任何框架(对于任何编程语言)有帮助?
要添加更多细节,UI是基于Web的,并使用JSP编写。
答案 0 :(得分:3)
这是管理同一应用程序的不同版本最困难的业务需求之一,因此不要指望该案例的开放框架,但是每个公司都会为此开发自己的系统。
对于业务逻辑修改,您将受益于强大的接口和 IoC (例如 Spring )。您将覆盖特定情况的服务并更改所需的方法,然后将修改后的服务版本注入IoC。
至于UI,它更难,因为你选择了JSP,它没有什么灵活性。当您使用Swing或GWT进行编程时,您可以以相同的方式进行UI修改 - 覆盖所需的UI类,更改它们,注入修改后的版本。使用JSP - 可以在定制版本中对.jsp文件进行大量修改。
现在更改修改/错误修复 - 完全使用版本控制系统。当然,您的客户特定版本是分支,而主要的标准版本是主干。对主干进行了错误修复,然后合并到客户特定的分支。通过接口/覆盖实现,大多数合并都是简单的方法,但是,对于JSP,我希望冲突经常发生......
通常,代码更改比基于XML的任何内容更容易合并。
答案 1 :(得分:2)
简单OOP怎么样?设置一个真实的接口/基类,并根据某种配置,实例化子类A或B,具体取决于客户端。很难为这样一个与语言无关的问题提供更多细节,但我认为这是非常现实的。
答案 2 :(得分:2)
这个问题的一个解决方案,在Win32 / .NET世界中很常见,是将特定于客户端的“代码”移动到资源文件中。许多.NET项目(.NET通过System.Resources命名空间内置对此模式的支持)使用此模式进行国际化,方法是将UI字符串放入每种语言的一个文件中,然后从相应的文件中加载UI字符串在运行时。
此模式如何应用于JSP应用程序?好吧,在这里你可以为每个客户端保留一个资源文件(或者,而不是文件,使用数据库),并在每次提供页面时从资源文件中加载用户特定的自定义文件。
例如,假设您的最大客户希望将徽标覆盖在您网站中每个网页的某些部分上。您的页面可以加载CustomerLogo
属性,并将其用作页面该部分的HTML图像的src属性。如果您正在向重要客户提供页面,则加载URL“/static/images/importantCustomerLogo.png”,否则您将回退到默认资源文件,该文件指定URL“/static/images/logo.png 。“
这样,您可以将用于加载属性的代码抽象为一个或两个Java文件,并在整个网站中使用这些属性。代码库中唯一一个特定于客户的部分是资源文件集,它们可以是一种易于阅读和修改的干净XML格式。结果是,那些没有首先开发应用程序的人可以在不必先读取代码的情况下修改XML,因此您不必维护资源文件 - 销售部门可以为您完成这项工作。 / p>
答案 3 :(得分:1)
GWT通过名为deferred binding
的功能开箱即用编译GWT应用程序时,编译器实际上会为每个不同的浏览器生成不同版本的代码。这是自动开箱即用的,GWT组件负责不同的浏览器细节。
此功能可以扩展为根据自定义属性生成任意编辑。这是一个简化的示例:假设您对普通视图和详细视图有不同的视图定义
public abstract class AbstractView { ....}
public abstract class NormalView extends AbstractView { ... }
public abstract class DetailedView extends AbstractView { ....}
你可以创建一个模块定义来生成两个不同的版本,一个使用NormalView
类,另一个使用DetailedView
(在你的gwt.xml文件中)
<define-property name="customMode" values="normal,detailed" />
<replace-with class="com.example.NormalView">
<when-type-is class="com.example.AbstractView" />
<when-property-is name="customMode" value="normal" />
</replace-with>
<replace-with class="com.example.DetailedView">
<when-type-is class="com.example.AbstractView" />
<when-property-is name="customMode" value="detailed" />
</replace-with>
使用
AbstractView view = GWT.create(AbstractView.class);
将在运行时提供适当的实例。
您可以将特定于客户端的代码封装到特定的类中,并为不同的实现公开通用接口。
您还需要根据当前查看的客户端选择适当的编译版本(您可以使用jsp。)
请不要将上面的代码示例作为测试,可能会出现语法问题,它只是为了传达一般的想法
JSP后端是GWT应用程序的理想托管环境,您将能够利用requestfactory机制轻松实现客户端和服务器之间的通信。
显然这里有一个学习曲线,IMO official documentation是一个很好的起点。
答案 4 :(得分:0)
我想您可能会尝试阅读与OSGi相关的文章(或书籍)......这个平台将为您提供一个非常实用的模块化问题的答案。它专门设计为能够处理与依赖项一起生活的不同模块和版本控制。 正如在答案的早期提到的,通过OSGi声明服务的依赖注入是Spring的一个非常有价值的替代方案,具有动态功能。部署提供服务的包和您的引用将自动更新,丢弃它,它们也将被刷新。 .. 看看这项技术后再问一些问题? 问候 杰罗姆