2008-10-29 3 views
3

J'ai une application web qui a plusieurs visages et jusqu'ici j'ai implémenté cela en créant des thèmes. Un thème est un ensemble de html, css et images à utiliser avec le backend commun.Meilleures pratiques pour la gestion de plusieurs versions spécialisées d'une application

Les choses sont disposées comme ceci:

code/ 
themes/theme1 
themes/theme2 

Et chaque instance de l'application Web a un fichier de configuration qui indique que le thème devrait être utilisé. Exemple:

theme="theme1" 

maintenant de nouvelles règles métier me demandent d'apporter des modifications à certains thèmes qui ne peuvent pas être atteints par le changement simplement les html/css/images et nécessitent de changer le back-end. Dans certains cas, ces changements doivent être appliqués à un groupe de thèmes.

Je me demande comment le mettre en page sur le disque et comment le gérer en code. Je suis sûr que quelqu'un d'autre a dû se battre contre ça.

Une idée est d'avoir:

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

alors que mon code commun mis la include_path telle que code/theme1 est recherché, puis code/common.

Alors si je veux me spécialiser dire la classe pour theme2, je peux simplement LogoutPage copier la page de code/common au même chemin sous code/theme2 et il reprendra la version spécialisée.

Un problème avec cette idée est qu'il y aura plusieurs classes avec le même nom. Bien qu'en théorie ils ne seraient jamais inclus dans la même exécution, je ne serais pas capable d'étendre la classe de base d'origine.

Alors, que faire si je devais donner un nom unique à la classe de base? par exemple. Theme1LogoutPage extends LogoutPage. Un problème que je peux prévoir avec cela est quand un code commun (disons le Dispatcher) référence LogoutPage. Je peux ajouter des conditions au répartiteur, mais je me demande s'il y a une façon plus transparente de gérer cela?

Une autre option que je peux penser est de maintenir des branches séparées pour chaque thème, mais je pense que cela pourrait être beaucoup de travail. Une dernière chose à considérer est que les fonctionnalités peuvent provenir d'un thème et nécessitent ensuite de fusionner dans la base de code commune.

Toute contribution grandement appréciée. Si cela fait une différence, c'est un environnement LAMP.

+0

Pourquoi voulez-vous downvote ma question? Il y a un million et un sondages sur ce type de dogfood que vous nourrissez votre chien. Ceci est une question de conception valide. Pourquoi ne pas simplement l'ignorer si cela ne s'applique pas à vous? –

Répondre

1

Je n'ai pas de recommandation particulière. Cependant, je suggère fortement de pas prendre un raccourci ... Utilisez la solution que vous trouverez à l'aise pour ajouter un troisième thème ou pour changer quelque chose l'année prochaine.
La duplication est l'ennemie de la maintenabilité.

+0

Merci pour les commentaires Hapkido. Je suis d'accord avec votre déclaration sur la duplication. –

1

Je voudrais étudier l'utilisation du modèle de stratégie comme un moyen d'implémenter différentes fonctionnalités dans différentes versions du site. Avoir une usine qui prend en charge votre configuration et fournit la stratégie de code appropriée basée dessus. Chaque stratégie peut implémenter une interface commune afin qu'elle soit interchangeable du point de vue de la classe appelante.Cela isolera vos modifications pour implémenter de nouvelles stratégies dans la classe Factory, la classe Configuration et toutes les nouvelles classes de stratégie à implémenter pour effectuer la modification. Vous pouvez faire la même chose (ou similaire) avec les contrôles utilisateur qui doivent différer entre les différentes versions.

Je vais illustrer par pseudocode (qui peut sembler louche, comme 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; 

     } 
    } 
} 

Exemple d'utilisation:

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

Merci pour la réponse détaillée! Donc, ce que vous suggérez, c'est qu'il devrait y avoir un code de base. Le code ne doit pas être spécialisé en fonction du site prévu, mais de ses fonctionnalités. Ensuite, un fichier de configuration (par site) indiquera quelle fonctionnalité est offerte aux utilisateurs par ce site. Est-ce correct? –

0

Utilisez-vous des pages maîtres? Si vous avez besoin d'une mise en page et d'une interface utilisateur différentes, vous pouvez avoir un ensemble de pages maîtres différent pour chacune de vos instances. Si vous avez besoin d'un comportement personnalisé, vous pouvez vous intéresser à l'injection de dépendances. Spring.NET, etc.

+0

Vous avez modifié votre question pour indiquer que votre environnement n'est pas ASP.NET. Je répondais de l'hypothèse que vous étiez dans ASP.NET. Pardon. – sliderhouserules

0

Vous avez besoin de modèles. De là, vous pouvez séparer votre code de votre présentation.

Je recommande fortement les modèles intelligents. Aussi PEAR template_it.

http://www.smarty.net/

Cela rend également votre code beaucoup plus maintenable. Le but est de ne pas avoir de code HTML dans votre php, et de n'avoir aucun php dans votre code HTML.

alors tout ce que vous devrez faire est de changer le modèle html qui est utilisé pour chaque thème. ou un dossier de modèles.

0

Vous pourriez avoir: /common/code

Et: /sitename/code

Tous les fichiers/common/code sont des classes abstraites. Pour chaque fichier dans/common/code, il suffit de créer un fichier de classe non-abstrait correspondant dans/sitename/code qui hérite de la classe abstraite dans/common/code.

De cette façon, il vous suffit de mettre en œuvre des changements dans le/sitename/code Tout le reste est une fonctionnalité de base qui existe uniquement dans/common/code

La chose importante à faire ici est de vous assurer que vous ajoutez seulement publique méthodes pour les classes abstraites. De cette façon, les méthodes sont disponibles pour tous les sites, et les classes de tous les sites peuvent être traitées/travaillées de manière identique.

0

je ferais:

[nom du thème]/[subfolder] default/commune default/common/html default/common/css rouge/code rouge/commune rouge/common/html rouge/commune/rouge css/code vert/commune vert/common/html

donc, si le code ou tout autre composant n'existe pas retombera à défaut.

Mais en fait je branche le site web en svn, donc du code commun si ça évolue je peux le fusionner, etc.voir Subversion à: http://subversion.tigris.org/

Questions connexes