Tuesday, January 8, 2013

Software Guidelines: Coding principles, Usability, Test

This is a part of the blog series about (SOA) software guidelines. For the complete list of the guidelines (i.a. about design, security, performance, operations, database, coding, versioning) please refer to: http://soa-java.blogspot.nl/2012/09/soa-software-development-guidelines.html


Coding principle

  • Follow the best practices / style guidelines in your programming environment / programming language. Use automatic style checking (e.g. findbugs, checkstyle, PMD).
  • Strive to self-documented code. Add comments if necessary. Use Javadoc.
  • Use a good IDE (e.g. Eclipse, VisualStudio) and good tools (e.g. SOAPUI for web service test, Maven for build, Hudson for continuous integration, Trac.)
  • Use software configuration management (SCM) system (e.g. SVN)
  • Use proven design patterns and beware of anti-patterns
  • Limit accessibility: e.g. declare classes/methods/fields as private instead of public
  • Loose coupling, strong cohesion e.g. Spring dependency injection.
  • Aspect oriented programming, separation of concerns (e.g.  Spring AOP for logging, security, transaction, error handling, cache)
  • Use declarative configurations instead of programmatic coding for cross cutting concerns (e.g. WS-policy for security) . The code ideally only focus to the business logic, has little knowledge of the framework (e.g. using AOP & declarative transactions in Spring to hide the underlying transaction mechanism).
  • Use templates to reduce coding (e.g. Spring DAO templates, Velocity JSP templates)
  • Use standard library/solutions don't reinvent new wheels.
  • If you use multithreading: beware of locking effects to the performance, beware of race condition
  • Defensive programming:  test before executing (e.g. null checking in Java/BPEL), handle exception gracefully, protect from bad inputs (validate, substitute with legal values).
  • Beware of common errors in your development language (e.g. null pointer exception in Java or buffer overflow in C++)
  • Use abstraction layer (e.g. use JAAS for authentication, DAO layer for database access) for loose coupling / flexibility
  • Choose libraries, vendors, tools carefully, consider e.g. maturity, popularity, support, future viability
  • Use thin clients (more robust, better performance)
  • Use early/static binding for better run-time performance
  • Use pre-assign size instead of using dynamic growth datatype
  • Use pre-assign number of parameters  instead of using dynamic number of params
  • Build the instrumentation up front during coding, e.g. test (TDD, performance measure), logbuild/deploy script.
  • Reuse result (e.g. using temp variables) to reduce number of calls
  • Use implicit interface instead of explicit to reduce method call overhead.
  • If you use asynch/multithreading, do you have message timing/sequencing problem en how to deal with this problem? e.g.  if the software received 3 message events (in arbitrary sequence) which are order interdependent?
  • Write a short "getting started" developer document (e.g. designs, data models, class diagrams, dependencies, configurations, service request/response examples, troubleshooting / error scenarios). This document will be especially useful when you act as an external consultant / temporary project developer or if you need to pass the project to other colleagues (perhaps you leave the company, or have to take another project, or get promoted :).

Version management

·         How the services & wsdl/schemas (e.g. common data model) are versioned?
·         How the services are retired? Do you consider back compatibility? How many back-versions will you keep maintain?
·         Provide standard structures in the software configuration management/SCM folders (e.g. folders for Java codes, BPEL codes, WSDL, XSD, XSLT/Xq,  test codes, server-specific-deployment-plan, project documentations, project artifacts/deliverables).
·         Minimum codes in the SCM, no prototypes (which might ignores some QoS such as security) / deprecated codes in the head SCM revision. Put the prototypes in the branches.
·         Minimize the amounts of jms resources: use the same channel for different message versions (e.g. identified by version tag in the soap header/namespace) so instead of using 3 topics (updateEmployee1.1, updateEmployee1.0, insertEmployee1.0) you can use only 1 Employee topic for better manageability & performance. If your service can only process a specific version, use selective consumer pattern http://www.enterpriseintegrationpatterns.com/MessageSelector.html.

Test

  • Have test cases created for (all) user cases and functional requirements? Do you test all SLA/non-functional requirements (e.g. response time, availability/robustness, compatibilities)? Are the test cases tractable to the requirement numbers?
  • Have test cases were created for all exceptions (negative tests), include network failure
  • Have you test variety of data input (valid, invalid, null/empty ,boundary values, long input)?
  • Are the tests are reproducible (e.g. automated, documented, code available in SCM, test case inputs in the database)?  It's advisable to rerun the tests (regression test, performance test) when the administrator add a new module/patch, add a new service, or change configuration.
  • How do you perform regression tests to prevent side effects (e.g. triggered by Hudson/a continuous integration framework)?
  • Do you consider also exploratory tests? If the person who perform the exploratory tests has enough experiences? Do more experience person need to assist him for pair-tests?
  • Does the test environment is comparable with the production (e.g. hardware performance, security constraints, OS/software/patch versions, server configurations)? Do you use a virtual lab to clone the production environment for test (e.g.LabManager)?
  • Use realistic data.
  • See test checklists: http://soa-java.blogspot.nl/2012/09/test-checklists.html
  • Reconciliation test (e.g. for asynchronous processing, for automatic document processing): compare number of input orders with number of fulfilments/ outputs. This test to detect 2 problems: order that never be fulfilled, order that fulfilled twice.


Meer over software test:
Test checklists http://soa-java.blogspot.nl/2012/09/test-checklists.html
Development test http://soa-java.blogspot.nl/2012/09/development-test.html


Usability, GUI, User-friendliness

  • Involve users during GUI design, prototyping, test (e.g. regular Sprint demo)
  • Use iterative prototyping (e.g. Scrum sprint demo) for frequent user feedbacks.
  • Avoid complex pages. Keep it simple. Start with just enough requirement. Design and implement not more than what the requirements need. Use minimum number of GUI widgets.
  • Anticipate user mistakes (provide cancel/undo button,  defensive programming e.g. invalid user input).
  • Minimum user efforts.
  • GUI structure & flow/navigation are clear/intuitive/logicconsistent, predictable.  Use business workflow to drive GUI forms & flows design.
  • Conform to user culture (e.g. domain terminologies) and standard web-style (e.g. colors, typography, layout) at user organization.
  • User documentation / help provided.
  • Update GUI progressively with separate threads (using Ajax for example) to improve responsiveness.
  • Use paging GUI (e.g. display only 20 results and provide a "next" button).
  • Condition the user to enter detailed query in order to reduce the results and minimize the round trips of multiple searches.
  • Update the user with the application status (e.g. progress bar) and the manage user expectation (e.g. Your request has been submitted. You will receive the notification within 2 days.)
  • Inform the user to avoid surprise and confusion when the application will be forwarded to external application (e.g. before OAuth authorization confirmation,  before IDEAL money transaction).
  • Image cost bandwidth (especially for mobiles) so minimize image sizes & number of images.
  • Avoid expensive computation when the user waiting, use asynchronous pattern or render the result progressively.
  • When the backend is busy prevent the impatient users to resent requests that will hinder availability more by informing the user "e.g. your request is being processed, please wait"  or disable the submit button.
  • For mobile web/applications:
    • Reduce information (due to limited screen): use only about 20% information/features from the normal web version.
    • GUI components are big enough and well-separated for finger touch input.
    • Provide links to the normal (PC version) webpage or text-only (low bandwidth) version.
    • Device awareness & content adaptation e.g. viewport according to screen size.
See Web-GUI checklist http://www.maxdesign.com.au/articles/checklist/


Source: Steve's blogs http://soa-java.blogspot.com/

Any comments are welcome :)




No comments: