Introduction
This design pattern is one I use a lot and have done so for a long time, this might be similar to other patterns, if so please tell me so I can reference them. Although this looks like "yeah.. how else would you do this" take a look at you objects for passing data and see if they contain bloat that would be better to be reduced.Description
The Light Weight Object design pattern takes an object and reduces it to the absolute minimum for its intended purpose to increase speed and performance for systems. This means that you only pass the absolute bare object essentials rather than an object which is bloated with extra data and functionality that you might need (but most of the time don't). If you are passing large objects around in your application then it can be bad for performance, if you are passing hundreds or even thousands these between layers or are subject to serialization then this can have a very adverse effect on performance. This comes about by either design or function creep (or a mix of both).Design
Large object by design are very common as all the functionality and methods to support the data (properties) is kept in a single place and its fairly easy to create large function rich objects that serve your business requirements well. Large objects are self descriptive and looks impressive and have all the functionality required to perform functions over the object life-cycle.Function Creep
You start with an object, business or functionality changes come in; additional code added, after a couple of major changes the object starts to bloat, functions are added to make calling calls easier to use the objects and old methods are often not removed. The objects starts to bloat and bloat as new functions and products are added to the application.
Classic Design
One thing I've seem a lot in my development career is large objects, really large objects, C# classes with hundreds and even thousands of lines which carry a lot data and internal functionality.Object- 1,000l+ lines
|______ Properties
|______ Methods
|______ Data Layer
|______ Serialization
|______ Business Logic
|______ Other Stuff...
I've seen large objects with as seen above with a mix or all of the items mentioned.( and some with even more than you could imagine). This is extra baggage and is carried and supported by the system by functions that might be used or only used at initialization or used rarely.
Light Object Pattern
Keep the object you are passing around as small as possible and use service classes or layers to get data or perform functions as you need it.Light Object -- 50 lines
Data Layer -- 300 lines
Business Logic -- 300 lines
Other Stuf -- nnn lines
Rules
- Keep the object as small as possible
- Remove methods to service layers
- Only have a single use for the object (split if dual functions)
- Remove unused properties
When To Use
Use when you need to keep objects small and light ( you really should be doing this by default as good practice). if they are going to be placed in collection or used in large volumes. If you are running very large volumes of data in memory than this can make huge difference to your capacity and the performance of you systems. Although know your scale, will I have 100 users or 1 Million users on this system.Pros
- Lots of objects take up less memory
- Quicker proccessing
- Better OOP : encapsulation, single use,
- Better Testing
Cons
- More complex code
- More re-factoring required
- Objects are not as self descriptive
- Developer has to know how to process the object
Example
Bob has a user object that contain the following which is created at login and held in session with the user. This is fairly standard and not as bloated as we think with of very large objects. Bob has noticed that each user only takes up a few kb (kilo-bytes) of memory per user, but this is not really much but the amount of users is starting to hurt.
The user object
public class User
{
public string SessionId { get; set; }
public int UserId { get; set; }
public string UserName {get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string Address CurrentAddress { get; set; }
public DateTime LastLogin { get; set; }
public DateTimecDateJoined {get; set; }
public Bool AccountActive {get; set; }
public Bool LoggedIn { get; set; }
public string Address[] PreviousAddress { get; set; }
public string SecretQuestion { get; set; }
public string Secret Answer {get; set; }
public void Log (string message }
public void Dispose()
public bool Validate()
public void Logout()
private Log _log
}
This looks like a standard object, not too big with a few standard methods you would expect.
But Bob has a problem, his user base is getting close to 250K users and the cost of his cloud bill seems to be going up a lot faster than the users on the system. So Bob starts with the user object which is held in session for every user.
What can go or stay and why
- SessionId Not Needed, copy of system session field
- UserId Keep used in code
- UsedName Keep used for display
- FullName lose : used rarely
- Email lose : used rarely
- Password delete not required in this
- Address x 5 lose : used rarely
- Last Login delete not used
- Date Joined delete not used
- AccountActive delete: If not active then it this object can't exist in session
- Logged In delete: if not logged in then object not in session
- Previous Address delete: never used
- Secret Question delete : never used after login, only on lost password
- Secret Answer delete : never used after login, only on lost password
- Method : Log move to service class
- Method : Dispose move dispose to service class as can be handled by session end or logout
- Method : Validate move to service class
- Method : Logout move to service class
- Method : Other move to service class
- Object: Log remove embedded logging object (NLOG, Log4Net etc..)
As can be seen you can reduce the user object for session storage to something like this
public class LightUser
{
public int UserId { get; set; }
public string UsedName { get; set; }
}
Although this does not represent the full user object/details it does cover the user object used in 99% of the cases 99% of the time.
Now bob can squeeze more session user objects in the same memory space, he may have to make more calls to the service layers but this is a lot less cpu than the storage and service of the larger object footprint.
No comments:
Post a Comment
Comments are welcome, but are moderated and may take a wee while before shown.