Showing posts with label software-engineering. Show all posts
Showing posts with label software-engineering. Show all posts

Saturday, April 1, 2017

MVP : Event Bus pattern instead of Listener

This question more towards paradigm. Why is that we don't use Event Bus instead of listeners in an MVP environment ? Typically, the "P" part has dependency injection of view and model references. Sure this has an advantage of showing explicit contract between the view and model via presenter, which is more readable.
However, wouldn't it be a cleaner approach to have presenter listen to events from views and events carry the view payload (eg: json representation). Same is the case with presenter talking back to the view. View will listen for events from presenter. Major advantage is, we don't have to write interfaces for each contract between view and presenter. If you look at the code you will see that presenter is getting exposed to view details like Text Fields, which i believe is increasing coupling between view and presenter. Say, if i'm replacing front end JavaFx instead of Vaadin, i will have to alter presenter as well.
This class is an example from a live project. Here we have different types of events ie i don't create event class for different cases. Eg: LoginViewEvent , DashBoardEvent etc which i believe is a maintenance pain.
public class UrayEvent {

    public static enum EventType {

        SESSION_SELECTED(1),
        DOCUMENT_SELECTED(2),
        DOCUMENT_EDIT_COMPLETE(3),
        DOCUMENT_EDIT_CANCELED(4),
        SHOW_SESSION_TABLES(5),
        SHOW_SESSION_DOCUMENTS(6),
        SHOW_SESSION_COLLABORATORS(7),
        USER_REQUESTED_REFRESH(8),
        AUTO_REFRESH(9),
        TABLE_SELECTED(10),
        DETACHED(11),
        SCHEDULER_NAVIGATION(12),
        JIRA_USER_SELECTED(13),
        DOCUMENT_SAVE_SUCCESS(14),
        DOCUMENT_SAVE_FAILURE(14);

        private final int value;

        private EventType(int value) {

            this.value = value;
        }

        public int getValue() {

            return value;
        }
    }

    public static class Event {

        private final EventType type;
        private final Object payload;

        public Event(EventType type, Object eventPayload) {

            this.type = type;
            this.payload = eventPayload;
        }

        public EventType getEventType() {

            return type;
        }

        public Object getEventPayload() {

            return payload;
        }
    }

}
Simple enough, the view send the event  DOCUMENT_EDIT_COMPLETE .The presenter layer handles this event. I found this way, a better way to decouple views from presenter.
    @Subscribe
    public void handle(UrayEvent.Event event) {

        switch (event.getEventType()) {
            case DOCUMENT_EDIT_COMPLETE:
                  // event payload contains document model data
                  // like document id etc
                 saveDocument(event.getEventPayload);    
                break;
            default:
                break;
        }
    }
Advantage
  • Less boiler plate code, 
  • For n-views we don't need n-interfaces
  • New event means adding event element to enum and updating respective subscribe methods handling this event.
Disadvantage
  • Memory leak if we forget to unregister  from eventbus (faced it plenty of time)
Questions
1) This approach means, there would larger set enum elements as the application grow. Is this approach an anti pattern ?
2) As we saw it uses Event Bus extensively are there any drawbacks of using bus system instead of interface-listener pattern ?
Wanted your valuable suggestion on this regard. The main issue is, if i blindly apply this pattern extensively across the project i shouldn't regret doing so, what would be a possible pitfall in this approach.

Friday, February 17, 2017

Git Build Number Generator

This tool generate version or build information in a source file format from a pointing local git repository, during the pre-build phase. Currently only supports java code generation. However can be extended to a more generic plugin based system to support other programming languages.

Tool favors command line arguments instead of configuration files to read the parameters, this decision is to speed up the tool, as this tool may be run numbers of times in a time slice.

You can use this in your build script in pre build phase, use in eclipse without a build script is just a use case. Policy of when to run is left to your creativity.

Usage

gbn git-repo-directory version-file-directory package-name 

  • git-repo-directory : Absolute path to local .git directory
  • version-file-directory : Absolute path to the directory, to place version source file
  • package-name : Java package name


eg: gbn /home/myhome/gbn/.git /home/myhome/gbn/src/com/alkber/gbn/version/
com.alkber.gbn.version

- VersionInfo.java -
package com.alkber.gbn.version;
/*
 * This is an auto generated file, modifications will not persist.
 * 2013/09/22 08:48:52
 */ 
public class VersionInfo {
                                                            
    public static final String buildNumber = "master.11.71740cc";
    public static final String branch = "master";
    public static final String commit = "11";
    public static final String version = "71740cc639811a5c4249f4344fe5e8586a7a494b";
    public static final String shortVersion = "71740cc";
                                                            
}
- VersionInfo.java -

It is highly advised to place .gitingore in the version-file-directory with .gitingnore content being 'VersionInfo.java'. As this file is updated frequently, it may cause git issues during commit and merge.Further to avoid git issues ignore the *class files.

Simplest Use Case

In eclipse, Goto Project->Properties->Builders , create a new builder

Location: [ path to java binary ]

eg: [ /home/myhome/bin/dk1.7.0_25/bin/java ]

Arguments: [ arguments to java binary]

eg: java -jar /home/myhome/bin/gbn.jar \ 
/home/myhome/git/Click2Limo/.git \ 
/home/myhome/git/Click2Limo/Click2Limo/src/com/frooday/click2limo/version/ \ 
com.frooday.click2limo.version

In the refresh tab of new builder setting specify the resource ie our version source file to be refreshed when ever tool is run.

In Build Options tab,

Enable-
  • Allocate Console
  • During Manual Build
  • During Auto Build
  • During Clean