latest posts

Nov 11, 2012

As months and years go by, devices coming and going I've seen (as most have) an increasing demand to provide a universal experience no matter what device you are on i.e. mobile, desktop, laptop, tablet, website etc. This has driven a lot of companies to pursue ways to deliver that functionality efficiently, both from a monetary standpoint and a performance perspective.
A common practice is to provide a Web Service, SOAP or WCF for instance, and then consume the functionality on the device/website. This provides a good layer between your NAS & Database server(s) and your clients. However, you don't want to provide the exact same view on every device. For instance, you're not going to want to edit 500 text fields on a 3.5" Mobile screen nor do you have the ability to upload non-isolated storage documents on mobile devices (at least currently). This brings up a possible problem, do you have the same Operation Contract with a DataContract Class Object and then based on the device that sent it, know server side what to expect? Or do you handle the translation on the most likely slower client side CPU?
So for me, there are 2 possible solutions:

Create another layer between the OperationContract and the server side classes to handle device translations

Come up with something outside the box

Option #1, has pros and cons. It leaves the client side programming relatively the same across all platforms and leaves the work to the server side so pushing out fixes would be relatively easy and most likely affect all clients if written to use as much common code as possible. However, it does leave room for unintended consequences. Forgetting to update all of the device specific code and then having certain clients not get the functionality expected. Further more, as devices evolve, for instance the iPhone 1-4S had a 3.5" screen while the iPhone 5 has a much larger 4" screen. Would this open the doors to having a closer to iPad/Tablet experience? This of course depends on the application and customer base, but something to consider. And if it makes sense to have differing functionality passed to iPhone 5 users versus iPhone 4, there is more complexity in coding to specific platforms.
A good route to solve those complexities in my opinion would be to create a Device Profile like Class based on the global functionality, then when the request to push or get data, the Factory classes in your Web Service would know what to do without having tons of if (Device == "IPHONE") conditionals. As more devices arrive, create a new profile server side and you'd be ready to go. Depending on your application this could be a very manageable path to go.
Option #2, think outside the box is always interesting to me. I feel like many developers (I am guilty of this too), approach things based on previous experience and go through an iterative approach with each project. While this is a safer approach and I agree with it in most cases, I don't think developers can afford to think this way too much longer. Software being as interconnected with external APIs, web services, integrations (Facebook, Twitter etc.) and countless devices is vastly different than the 90s class library solution. Building a robust as future proof system to me is much more important than the client itself in my opinion.
That being said, what could you do? In working on Windows Workflow Foundation last month and really breaking apart what software does at the most basic level, it really is simply:

Return the data the Client expects (hopefully incorporating error handling in the return)

So how does this affect my thinking of architecting Web Services and Client applications?
I am leaning towards creating a generic interface for certain requests to get/set data between the Server and Client. This creates a single funnel to process and return data, thus eliminating duplicate code and making the manageability much higher. However, you're probably thinking about the overhead in translating a generic request to "GetObject" to what the client is actually expecting. I definitely agree and I don't think it should be taken literally especially when considering performance of both server side resources and the amount of data transferring back and forth.
What I am implying is doing something like this with your OperationContract definition:

Then implement that Factory pattern for each object class. I should note implementing a Device Profile layer could be done at the Factory Constructor level. Simply pass in the Device Type inside the ClientToken object. Then a simple check to the Token class for instance:

You could also simply store Device Profile data in a database, text file, xml file and then cache them server side.
Obviously this is not a solution for all applications, but has been successful in my implementations.
Comments, suggestions, improvements, please let me know below.