Archive for October, 2008

What makes a good component/service?

Wednesday, October 1st, 2008

A few collected thoughts & notes from around the web regarding what makes a good component/service.

  • Interface – all implementations share this. Should have few methods, use data objects as return values, take primitives as inputs, throw only custom exceptions, and be very, very well documented.
  • Implementations – implement the logic behind the service. May provide extra features such as caching, or such things as optional collaborations.
  • Data – data objects this service deals with. Should be immutable, comparable, cloneable as much as is possible. Should be serializable/XML/Persistance annotated in most languages.
  • Storage – Data (or data.io) package should define storage API, and an in-memory data store. Allow other services/projects/subprojects to define database backed or other kinds of data stores.
  • Cache – Data.Cache packages should define cache API? (or can this be standard per runtime?) Who should be in charge of caching? The service itself, or the user of the service?
  • Use dependency injection for all services/data stores it requires. Use constructor-injection as much as possible.
  • Throw errors early – in constructor if possible.
  • Exceptions – custom exceptions for high level categories of erroneous behavior (try not to do one for every possible condition – classify, and wrap). Don’t re-throw exceptions from other frameworks – wrap in custom exception.
  • Make behavior configurable via dep injection as much as possible. Use filters or strategies.
  • Inject 1 configuration object instead of many options. Standardize on configuration API/Framework for each runtime/language.
  • Standardize on logging framework/API for each runtime/language, and make sure it’s used (instead of System.out or simliar)
  • Provide events/messages and/or hooks for important happenings so others can do things pre/post.