etlds
etlds

Reputation: 5890

How (what design pattern) to handle adding new fields?

I have been doing web app for medical data collection for a long time. Clients always have this kind of request : adding a new field in the form, for example they want add "gender" in demographic form.

Every time they request, I have to
1. Add a new textbox on the page.
2. Add a new field(property) in my demographic form class.
3. Change my business logic for saving the form to DB.
4. Change my business logic for loading the form from DB.
5. Add a new column in the Database table.
6. Alter the Store Procedure for insert and update the demographic table.

I have to make changes on every layer, every module(UI, business layer, data access layer, db), and I feel it is stupid.

How can I handle this kind of change? What pattern should I use?

Upvotes: 1

Views: 475

Answers (2)

stan0
stan0

Reputation: 11817

Not exactly a pattern but here's an idea:

You could store all the form fields in a map/table/dictionary in your Demographic class.

  1. add the field in the UI
  2. add it's value to the class' map/dictionary for a predefined key
  3. save the map/dictionary to your DB by using each pair's key as a column name
  4. populate the map/dictionary from you DB inserting a pair with the column name as a key
  5. on save check if there is a column for that key. If not - add one
  6. using this approach notify your logic that the map/dictionary was updated and update your CREATE query with the new column (key)

Upvotes: 0

Bartek Banachewicz
Bartek Banachewicz

Reputation: 39390

Something like an ORM would be helpful here. I'll give you an example from Django framework. I am not saying you should use this one in particular, but its tutorial illustrates the concept nicely.

That's our model class:

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published)

It generates this DB query:

BEGIN;
CREATE TABLE "polls_poll" (
    "id" integer NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "pub_date" datetime NOT NULL
);
COMMIT;

Then, you can easily view all of the Polls:

class IndexView(generic.ListView):
    model = Poll                        # specifies model
    template_name = 'polls/index.html'  # specifies HTML template

Template could look like this:

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

It could use automatic field iteration to display either the data of the inputs, instead. Django automatically chooses appropriate type of input to match the type of data.

Now, when you add a field to Poll class, it automatically propagates to database creation and extraction queries, and the form incorporates the newly added field.

Different frameworks behave slightly differently, of course, so you would need to review them before using. All of them usually supplies you with the tools to solve your problem, and tweak where the generic solutions aren't enough.

Upvotes: 1

Related Questions