Repository pattern

In this post I’d like to talk about composition and inheritance on practical example.

Intro

First of all I’d suggest to read about Repository pattern of EAA.

Here you can read more about database schema which we will use in this post. Finally take a look at layered architecture concept of our app.

Lets consolidate all previous materials by implementing UserPermissions service. I’ve posted base concept of this service here, but  domain model has been slightly changed during actual implementation.

Here is the Use-Case sketch of our service:
PermissionsService Use-Case

Service should provide methods to grant user permissions (using jabberID and chat room name) revoke and modify them.

If there is no such a user in database having given jabberID, new user should be created and mapped to database (e.g. persisted). The same action should be performed with new chat room.

Lets assume that database tables contain this information:

db_items

As you can see we have got three users – Steeve, Mark and John sitting in it@conference.xmpp.org

Personal information is stored in users table. Information about chat rooms is stored inside rooms table. Finally permissions table is used to link all this information together with acess level for each user.

Note that Steeve and Mark both have multiple jabber accounts and use them to talk in the same chat room. This situation is perfectly handled by our db schema.

Here is the sequence of actions that should be performed when new user luke_skywalker@xmpp.org joins chat room it@conference.xmpp.org:

  1. New user with empty personal information should be created and mapped into users table
  2. No new rooms should be created/mapped
  3. User should be assigned zero access level since he is new user, we know nothing about him etc
  4. New record should be inserted into permissions table according to steps (1)-(3)

So generally we should invoke three database mappers to create and register new user (one mapper per database table).

Access level lookup

Our service should allow client to get access level value, using user’s jabberID and chat room name. If you will review our use case sketch again you’ll notice that this use is specially marked in red.

This is time critical operation. From this point of design all plugins will use this operation in order to check if user has enough rights to execute plugin content (e.g. command, action etc).

In this situation we will use HashMap with complex key. Our service will be responsible for building this HashMap using database entities and domain objects and manage it during lifetime. When new user is added/deleted or access level is changed service should edit HashMap as well.

Architecture

PermissionsService (Class)

Here is how we create service:

  Repository repo = new Repository(db);
  UserPermissionsService service =
  	new UserPermissionsService(repo);
  //dowork with service
  //...

As you can see from class sketch our permissions service stores reference to Repository class. In order to create new user/room or insert permissions record permissions service accesses Repository. Using this design we’ve isolated service from database mappers and all other database stuff.

Repository on the other hand is responsible for caching users and rooms using Identity Maps. It is also used as OR-mapper (provides getPermissions() method) for getting UserPermissions records list. This list is used by our permissions service in order to construct permissions lookup HashMap.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: