How To Refactor Struts Action Classes To Service Facade Pattern

The Goal

The goal is to remove business logic and entities from the struts action classes and their associated JSP's.

Note: rather than refactoring legacy Struts Action classes, the approach is being taken to simply replace Action classes and JSPs with SpringMVC/Webflow and Freemarker pages.

The Approach

The approach is to first push down all business logic and knowlege of business entities into a service facade that is responsible for two things:

  1. It shields the presentation layer from any business knowlege
  2. It shields the domain layer from any knowlege of presentation data.

Steps to achieving this

  1. Find the Struts action integration test that verifies the action class you are refactoring. Run this(in eclipse) before starting any refactoring and run it again and again after changes to pick up on any possible problems
  2. Consider inline refactoring private methods in action class where possible. This helps identify cases where unnessecary queries are repeated or data is put into session.

There are typcially two types of refactoring which are:

Data Retrieval and Display

  1. Inspect the JSP file and identify places where 'xyzBO's are being used and create DTO with data that matches the data being used from the 'xyzBO'.
  2. Create your service facade method that is responsible for returning the DTO to be used by the JSP. * All business related code in action class gets 'pushed down' into this method. i.e. 'xyzPersistence.xxxx', 'xyzService.xxxx'
  3. Define the service facade interfaces and DTOs in the serviceInterfaces module (so they can be accessed by new UI code in userInterface module-- see SystemInformationServiceFacade as an example).

Create or Update of Business Entities

  1. Create your service facade method that is responsible for delegating to correct 'xyzService' for creation or updates.
  2. You should consider creation of DTOs that represent the data required for either creation or update.
  3. You may need to look at 'pulling out' persistence behaviour from the business object or just defer from using it and use the DAO pattern instead.

Defining Your ServiceFacade Interface

List of Classes to Refactor

  • org.mifos.accounts.acceptedpaymenttype.struts.action
    • AcceptedPaymentTypeAction
  • org.mifos.accounts.fees.struts.action
    • FeeAction
  • org.mifos.accounts.fund.struts.action
    • FundAction (done)
  • org.mifos.accounts.loan.struts.action
    • AccountStatusAction
    • LoanAccountAction
    • LoanActivityAction
    • LoanDisbursementAction
    • MultipleLoanAccountsCreationAction
    • RepayLoanAction
    • ReverseLoanDisbursalAction
  • org.mifos.accounts.productdefinition.struts.action
    • LoanPrdAction
    • PrdCategoryAction
    • PrdConfAction
    • SavingsPrdAction
  • org.mifos.accounts.productsmix.struts.action
    • ProductMixAction
  • org.mifos.accounts.savings.struts.action
    • SavingsAction
    • SavingsApplyAdjustmentAction
    • SavingsClosureAction
    • SavingsDepositWithdrawalAction
  • org.mifos.accounts.struts.action
    • AccountAppAction
    • AccountApplyPaymentAction (done)
    • ApplyChargeAction
    • EditStatusAction
    • NotesAction
  • org.mifos.application.admin.struts.action
    • AdminAction
    • ShutdownAction (done)
    • SystemInfoAction (done)
    • ViewOrganizationSettingsAction (done)
  • org.mifos.application.collectionsheet.struts.action
    • CollectionSheetEntryAction (done)
  • org.mifos.application.holiday.struts.action
    • HolidayAction
  • org.mifos.application.importexport.struts.action
    • ImportTransactionsAction
  • org.mifos.application.meeting.struts.action
    • MeetingAction
  • org.mifos.config.struts.action
    • CustomFieldsAction
    • HiddenMandatoryConfigurationAction
    • LabelConfigurationAction
    • LookupOptionsAction
  • org.mifos.customers.center.struts.action
    • CenterCustAction (done)
    • CenterEditStatusAction
  • org.mifos.customers.checklist.struts.action
    • ChkListAction
  • org.mifos.customers.client.struts.action
    • ClientCustAction (done)
    • ClientTransferAction
  • org.mifos.customers.group.struts.action
    • AddGroupMembershipAction
    • GroupCustAction (done)
    • GroupTransferAction
  • org.mifos.customers.office.struts.action
    • OffAction
    • OffHierarchyAction
  • org.mifos.customers.personnel.struts.action
    • PersonAction
    • PersonnelNoteAction
    • PersonnelSettingsAction
  • org.mifos.customers.ppi.struts.action
    • PPIAction
  • org.mifos.customers.struts.action
    • CustAction
    • CustHistoricalDataAction
    • CustomerAccountAction
    • CustomerAction
    • CustomerApplyAdjustmentAction
    • CustomerNotesAction
    • CustSearchAction
    • EditCustomerStatusAction
  • org.mifos.customers.surveys.struts.action
    • QuestionsAction
    • SurveyInstanceAction
    • SurveysAction
  • org.mifos.framework.struts.action
    • BaseAction
    • PersistenceAction
    • SearchAction
  • org.mifos.reports.action
    • BirtReportValidationAction
  • org.mifos.reports.admindocuments.struts.action
    • BirtAdminDocumentUploadAction
  • org.mifos.reports.struts.action
    • BirtReportsUploadAction
    • ReportsAction
    • ReportsCategoryAction
    • ReportsDataSourceAction
    • ReportsParamsAction
    • ReportsParamsMapAction
    • ReportsUploadAction
    • ReportsUserParamsAction
  • org.mifos.security.login.struts.action
    • LoginAction
  • org.mifos.security.rolesandpermission.struts.action
    • RolesPermissionsAction