Posts Tagged Patterns

Lazy Bean Mapping and the Command Pattern

In doing some refactoring recently, I came up with a useful base class for my command pattern managers (manager beans that have a bunch of commands associated with them), here I will call it the LazyBeanManager.

Consider a case where you have a manger that manages a bunch of actions, and that you want the whole setup to be very lazy — only load the manager when it is used AND only load a command action when it is requested. This is very simple to accomplish. First assume you have the following spring config:

1
2
3
4
5
6
7
8
9
10
11
12
<bean id="manager" class="example.MyManager" lazy-init="true">
    <property name="commands">
            <map>
                    <entry key="cmdA" value="commandA" />
                    <entry key="cmdB" value="commandB" />
            </map>
    </property>
</bean>
   
<bean id="commandA" class="example.CommandA" lazy-init="true" />
   
<bean id="commandB" class="example.CommandB" lazy-init="true" />

You see that we have a simple command pattern configured. There is a manager which somehow routes control to a command bean. The first bit of laziness you should notice is the lazy-init="true" set on all three beans. This tells Spring not to load these beans until something else references them. The second bit of laziness is that the command beans are referenced by value (their bean id) rather than reference, which prevents the command beans from loading when the manager bean loads. At this point, Spring does not know how to do anything with the map of command beanIds. The following simple class will take care of that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MyManager implements ApplicationContextAware {
    private Map commands;
    private ApplicationContext context;
    public setApplicationContext(ApplicationContext context) throws BeansException {
            this.context = context;
    }

    public void setCommands(Map commands){this.commands = commands;}

    public void execute(String commandId){
            Command cmd = findCommand(commandId);
            if(cmd != null){cmd.execute();}
    }

    protected Command findCommand(String cmdId){
            Command obj = null;
            String beanId = MapUtils.getString(mappings,cmdId);
            if(StringUtils.isNotEmpty(beanId)){
                    obj = (Command)context.getBean(beanId,Command.class);
            }
            return(obj);
    }
}

Note: Some un-important classes are not shown here. This is just to give you the general idea of the manager.

You will notice that the ApplicationContext is injected into the manager by Spring through the implementation of the ApplicationContextAware interface. Now, when your application needs to execute one of these commands, you simply pull the manager bean out of spring (which will load only the manager), call the execute(String) method with the desired command id. Then, only the desired command bean will be loaded and executed.

This has come in very handy recently for handling front end interface actions. This laziness allows the system to start up faster, be more stable, and more memory efficient. Sometimes being lazy is a good thing. In my development, I have created an abstract lazy mapping manager using this strategy… it works great.

What I would like to come up with is a version of this that not only does lazy loading, but then unloads the bean after a period of idle time — I am not sure whether Spring currently supports this or not. Something to look into.

Popularity: 1% [?]

  • Share/Bookmark

Tags: , ,

Worker Bean Pattern

I stumbled upon something that I thought would make a good design pattern, if no one else has already come up with it. The only name I could think of for it was the “Worker Bean Pattern”; if this is not new, someone please let me know.

Basically the pattern consists of two classes, the Manager class and the Worker class. The Manager class is used to create semi-transient Worker classes as required for use by client objects. The example I will use to help me describe this pattern is a web-based wizard-style input form.

The Manager class is basically a loose combination of the Factory Pattern and the Singleton Pattern. There should be only one instance of a particular Manager object in the system. For my example, let’s call the Manager class FormManager and say that it is an object stored in the application scope of the server context (so that there will be only one instance per server context). The Manager class’ function is to “manage” the Worker instances. It creates them, populates their data, and destroys them with no external objects acting directly on the Worker classes in a fashion other than read-only. We can stub out the methods of our FormManager as the following:

1
2
3
4
5
public class FormManager {
        public FormWorker createFormWorker(){}
        public void postFormData(FormWorker fw, String name, String[] values){}
        public void destroyFormWorker(FormWorker fw){}
}

where FormWorker is the Worker. The createFormWorker() method is used to create a FormWorker or use by the client when they first enter the wizard form set. This Worker could be pulled from a pool of available workers or created as needed. The client puts the FormWorker the session scope. As the pages of the wizard form are submitted, each posts its data to the postFormData() method, which processes the data and modifies the FormWorker as necessary. Once the final wizard page has been submitted and the client has no more use for the FormWorker, it is passed to the destroyFormWorker() method so that it can be disposed of, or returned to the pool.

The Worker is basically an encapsulation of data required to perform an operation in the Manager that requires more than a single step. In our example that FormWorker is stored in the user’s session so that the current state of the wizard form is maintained between pages. The Worker’s data should not be accessible outside of the Manager. It exists only as a temporary extension of the Manager. Once the client has finished with a Worker it should be disposed of by the Manager. In our example, FormWorkers could be pooled within the FormManager to minimize new object creation and increase efficiency. Our FormWorker would look something like this:

1
2
3
4
5
6
7
8
9
10
public class FormWorker {
        FormWorker(){}

        void addData(String name, String[] value){}
        String[] getData(String name){}
       
        void setUserId(String userId){}
       
        public String getUserId(){}
}

You’ll notice that most of the methods have the default access, accessible to only other classes in the same package. You would want to place the FormManager and FormWorker in the same package for this to work. Another interesting means of achieving this association, if you prefer, would be to nest the FormWorker inside the FormManager as a static nested class; with a nested class, you can enforce the isolation of the worker using private methods. Let’s do that for our example and flesh out the methods a bit more for the final stub:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Manager
public class FormManager {

        public FormWorker createFormWorker(String userId){
                FormWorker fw = checkoutWorker();
                if(fw != null){fw.setUserId(userId);}
                return(fw);
        }

        public void postFormData(FormWorker fw,String name,String[] values){
                fw.addData(name,values);
        }

        public void destroyFormWorker(FormWorker fw){
                fw.clearData();
                fw.setUserId(null);
                checkinWorker(fw);
        }

        // Worker
        public static class FormWorker {
                private String userId;
                private HashMap data;

                private FormWorker(){this.data = new HashMap();}

                private void addData(String name,String[] value){
                        data.put(name,value);
                }

                private String[] getData(String name){
                        return((String[])data.get(name));
                }

                private void clearData(){data.clear();}

                private void setUserId(String userId){
                        this.userId = userId;
                }

                public String getUserId(){return(userId);}
        }
}

Obviously this is still missing some code and does not really do anything interesting; however, it should give you the basic feel of my idea. I used something similar to this in a project recently (actually, a wizard web form set) and it worked very nicely. Of course there are other ways to skin this cat. You could even simply put the “working” data into the session itself, though I tend to like things neat and tidy without having to keep track of a lot of session variables.

This may or may not already be a pattern on someone’s list or in a book somewhere, but I did not find it. I present it in the hope that it will be useful to someone, and as I said, I am always open for comments or suggestions.

Popularity: 1% [?]

  • Share/Bookmark

Tags: , ,

Switch to our mobile site