Creating Shared Applications - Enabling Client-Specific Settings

I created an open source application, and I would be interested to know how others handle client-specific requests. It is important for me that the application is simple; I am not trying to do everything for all people. Applications can be bloated, complex, and simply unusable. However, there are some client-specific options that would be nice (this just doesn't apply to all clients). For instance...

Say we have a domain object called Server. In the user interface, we allow the client to select from the list of servers. For one company, it is useful to filter servers by location (USA, Germany, France, etc.). Simply add a server property as follows:

public class Server { public Location Location { get; set; } // other properties here } 

My concern is that over time the server might swell with properties. And even if I only add space, not all customers will care about this property.

One option is to allow user-defined fields:

 public class Server { public string UserField1 { get; set; } public string UserField2 { get; set; } public string UserField3 { get; set; } // etc... // other properties here } 

Is this the best way to handle this? I do not like the fact that type safety disappears, doing everything in a row. Are there other / better ways people deal with such problems? Is there even a design template for something like that?

+4
source share
6 answers

In my opinion, a good design pattern for something like this is to use schemas at the database level, and then basic inheritance at the class level.

 CREATE TABLE dbo.A ( ColumnA INT NOT NULL PRIMARY KEY AUTO_INCREMENT, ColumnB VARCHAR(50), ColumnC INT, etc. ) 

And now we have a client that needs certain functions, so let’s create an extension for this table in a different scheme:

 CREATE TABLE CustomerA.A ( ColumnA INT NOT NULL PRIMARY KEY, Location VARCHAR(50) ) 

But now we have another client who needs to expand it differently:

 CREATE TABLE CustomerB.B ( ColumnA INT NOT NULL PRIMARY KEY, DataCenterID INT ) 

Although the fields may not be relevant, you get this idea, and so now we need to create client-side domain models:

 public abstract class A { public int ColumnA { get; set; } public string ColumnB { get; set; } public int ColumnC { get; set; } } public class CustomerA_A : A { public string Location { get; set; } } public class CustomerB_A : A { public int DataCenterID { get; set; } } 

So, now that we need to create something for client A, we will subclass them, as well as for clients B, etc.

Now, FYI, this is the beginning of a very dynamic system. I say that since the missing part, which is not yet dynamic, is the user interface. There are many ways that can be achieved, but is beyond the scope of this question. This is what you will need to consider. I say, because how you control the interface, you will define, as you even know, to create this subclass.

Hope this helps.

+2
source

The usual early approach is to use XML configuration files for this kind of thing. But programming for the specific needs of the client requires a whole lot of thinking around how you program. See this answer for a similar question.

+1
source

Of course, it always depends on how many settings you want to allow. In our product, we have come to the point where users can fully define their own objects with properties and relationships between them. Basically, each EntityObject, as we call our entities, at the end consists of a collection of values ​​and a link to a metamode that describes the values ​​inside them. We have developed our own query language, which allows us to query the database and use expressions that can be translated into any target language (although currently we only run SQL and .net).

The game does not end, and you quickly find that things like validation rules, permissions, default values, etc., become mandatory. Of course, all this requires user interface support, at least for the implementation of the metamodel.

Thus, it really depends on the number of settings that the end user must make. I assume that in most cases, simple user fields are enough, as you described. In this case, I would provide one field and save the JSON text. In the user interface, you can provide at least a semi-decent user interface that allows you to create structure and extensibility.

+1
source

Option 1: Say No .:-)

And although I say this (half) as a joke, there is some truth. Too often, developers open up to infinite customization, allowing one or two user-defined functions, setting the snowball in motion.

Of course, this should be balanced, and it looks like you can do it to a certain extent. But if you really want your application to be simple, keep it simple and do not add settings like this.

Option 2: Inheritance.

If you really need to add settings, I would rely on a way to create a base class with all the “standard” parameters, and then create client-oriented classes that contain optimizations for a particular client.

For instance:

 public class Server { // all standard properties here } 

Then for Joe Pizza you can:

 public class JoesPizzaServer : Server { public Location Location { get; set; } } 

The advantage of this is that it allows you to base your representations on the presentation from client (or base) models.

For example, in MVC, you can customize your view models as follows, and then you can have specific views for each client.

For example, Bob Burgers will have his own look at the base model:

 @model MyApp.Server @* implement the base form *@ 

Joe Pizza will use a custom model:

 @model MyApp.JoesPizza @* implement the base form -- a partial view -- with addtional custom fields 

MVC really well supports this type of template. If you are not using MVC (possibly WPF or web forms), there are still ways to use partial “view” files to achieve something like this.

Of course, your database can (and probably should) support a similar inheritance model. The Entity Framework even supports inheritance models like this.

+1
source

Maybe I'm wrong, but it looks like you want to process different versions of your software with the same code base. I can imagine two approaches for this:

  • Actually define different versions for it and process the changes for each client. This will not give you problems in terms of domain modeling, but it will require infrastructure support, which must be scaled according to your client requirements. There are some related questions (e.g. this , this, and this ).
  • Treat this at the domain model level as a user configuration. The advantage of this approach is that you do not need to include several versions of your software, but this is because your model is more general and potentially more complex. In addition, your tests should certainly be adapted to handle various scenarios. If you go in that direction, I would simulate an object representing an attribute (with name and value), and consider the Server class as having a set of attributes. Thus, your model still reflects your OO style requirements.

NTN

+1
source

I am approaching Python, which I think will be well heard - this is a dictionary. The key is the name of your field, value is the value, errrrr ... value;)

That would be easy enough to represent in the database.

0
source

All Articles