views:

110

answers:

2

I'm basically just posting tonight to get some feedback from some of you more experienced architects out there. I'm just starting to get into more use of Interfaces...already seasoned and know Abstract Classes which I've used in some pretty slick designs of my own.

Anyway, I created a hack UML here: uml.pdf

A few things about the diagram first:

>> Everything is a property that does not have () which of course is a method

>> Everything is public unless specified private

>> The fields or methods in blue are highlighting the additional class specific fields in addition to the interface members

>> I named the MainPhotoUpload a factory because that's how I see this right now working...at least in my mind it's a factory because it's grabbing a certain service instance based on the APIType

>> The two grey classes is just showing you that there's going to be other Wrappers I create later for other APIs such as Flickr and Picasa which will work in this same way...implementing these core Interfaces and using this pattern I'm showing with the Facebook example here

>> The properties you see in a service such as for example the FacebookPhotoService ... its FacebookAlbumPhoto property represents an instance of the FacebookAlbumPhoto so I can start working with it. In other words it does the instantiation for me and exposes it as a property in the FacebookPhotoService....so I can use the FacebookPhotoService . FacebookAlbumPhoto property to get an instance of a FacebookAlbumPhoto and start calling methods or other members of FacebookAlbumPhoto. So the service is like just a bridge to allow you to utilize the underlying core wrapper classes and start using them.

Ultimately the goal is:

1) Create as much reuse as possible for all the API wrappers we create going forward (Facebook, Flickr, etc.) pertaining to Photo specific functionality which is the scope of this model

2) Enforce a pattern across any API we implement so that they'll all be somewhat consistent at least on the core members that you're going to see in any Photo API out there. e.g. IPhoto, and the rest of the interfaces denote common properties and methods that you'll see in any Photo API like these

3) A way to ultimately call the wrapper methods as well as to obtain the current session for that APIn or to get other Facebook objects by calling methods on those objects (e.g. FacebookAlbumPhoto, etc.). So for example with Facebook, I want to be able to call the facebook methods for a certain class or access properties of a certain class indirectly by using a service. The Main service acts as a Factory that goes out and gets the right service. Then you use that service to ultimately start calling methods and utilizing the underlying wrapper classes (such as FacebookAlbumPhoto, etc.)

So this is what I've come up with. You'll see on page 2, some examples of how I envision these will be used in code later on for our business logic.

This is not done of course.

I want to know specific to that uml I created:

1) Is my approach at least seeming somewhat logical, respectable, usable and makes some sort of sense here? to me it is but I want to see what some other architects think out there. I mean I'm not looking for perfection here...just something that's fairly flexible and for now works and allows me to get at various services and that the way I'm using these services makes sense (i.e. having properties in those services that expose instances of sub classes)

2) Any advice on improving or changing this without getting overly crazy (I don't need to know about 5 design patterns in how I can improve this...just give me some basic advice on interfaces, service classes like mine, or factory etc. that pertain to the scope of this)

3) Anything I'm just doing totally wrong that is just clearly "Never do that". For instance my fellow architect friend says I'm creating interfaces here but not really providing any value. However for me it's providing some value to enforce some consistency/pattern and ultimately reuse for base commonalities between any Photo API wrappers we create later as well as I am actually using those Interface types in other classes later on such as the MainPhotoService.APIService property which I have as type IAPIService because I don't know which service I'll return until I check the incoming APIType enum in that constructor of the MainPhotoService.

4) Is that really a "factory" pattern? Is my approach logical and clean and extensible?

Looking at this with respect to understanding that I am now just starting to get really into hard core architecture, if you were to use this code, would you a) like the pattern..or at least tolerable for now or b) have some issues with the way I'm retrieving or using a service or the way I'm getting instances of those underlying classes, or the way I'm using (my intent in using) Interfaces here.

if anything is not clear or missing here, please ask. I really don't have anyone else to bounce this off of (no dev teammates, and friends are too busy).

+1  A: 

I agree with Jaroslav - I'd expect the various instance properties to be accessed via the IApiService interface.

(OK, my C# is rusty - in C++ I'd access an IPhoto interface by calling set/getProfilePhoto methods on an IApiService interface).

Following on from this, all your examples deal with Facebook specific classes, whereas I would expect them to be written in terms of generic interfaces (IPhoto, IApiSession etc.)

Without these abstractions you don't have a pluggable solution, which would appear to be the requirement.

Seb Rose
Ok, so my existing implementation is using IAPIService instance inside the Factory class as a property to give back the right service to the caller. I mean I am using it. I guess I don't see how I could use it for IPhoto...because what I really want is FacebookAlbumPhoto, not the base class FacebookPhoto
CoffeeAddict
You would add more accessors to IAPIService (e.g. IAPIService.getAlbumPhoto) that return the IPhoto interface onto the relevant instance. You would then manipulate the photo through the generic IPhoto interface.The goal is to be able to write code that uses services without caring which online provider is implementing the service. Any time your code needs to know which provider it is dealing with, you have brittle, non-generic code.
Seb Rose
There may be situations where not all providers offer the same services. There are a number of options in this case, which range from not providing access to these specialised services through the generic interface, through to signalling an error when you try to use a service that is not provided by the service implementation.
Seb Rose
A: 

Expanding a bit on what both Seb Rose and Jaroslav are saying, with respect to your interface IApiService.

The benefit of using an interface is this: If your factory hands me (the client code) an IApiService, I shouldn't need to know which IApiService I have in order to use it.

In your model, though, IApiService has no methods for retrieving photos. If I want a photo, I have to find out which IApiService it really is (Facebook), and access FacebookAlbumPhoto or FacebookProfilePhoto. Because the client is interacting with methods of FacebookPhotoService instead of IApiService, it defeats the purpose of the interface.

This is not to say that it's easy to fix. If you want to really get the most out of the interface, you have to design methods and properties of IApiService that can be used for all of your planned photo services. Maybe you'd choose to get photos via a method like IEnumerable<IPhoto> GetAllPhotos(), at the expense of the (Facebook-specific) distinction between Profile and Album photos... (You can always inspect the resulting IPhotos to see if they're FacebookAlbumPhotos, but you want to avoid that until it's necessary...)

Or maybe you decide it's valuable to have a method IPhoto GetProfilePhoto(), but you realize that some services might not have profile photos, so they'll return null (or the first photo in the collection, or whatever seems correct for that particular service). Maybe you add IEnumerable<string> GetTags() and IEnumerable<IPhoto> GetPhotosByTag(string Tag), and if one of your services uses Categories instead of Tags, you can hide that distinction under the hood.

You've provided a lot of detail about your architecture, but more info about your project's goals would be required to really help weigh these kinds of options.

(Also be aware that you have to make choices and future-proofing is never 100%. If this is going to be Facebook-only for the next 12 months, you can write it to be Facebook-specific now and refactor later. One advantage there is that, a year from now, you'll know more about your app and its evolving requirements than you do now. Hey, maybe the next big photo service you have to integrate isn't even online today!)

grossvogel