Reputation: 8036
[See below for updates]
I am having a hard time defining a pattern. My colleague says it's adaptor pattern. I'm not sure. We're stuck mainly because we want to correctly name our components.
Question: Is it adapter pattern? If not what is it? If it is something else, is this the best way to implement the idea?
To put it in summary, it is a main component(is this the adapter?) that shares an interfaces with sub-components (are these providers?). The main components decides/orchestrates which of the sub-components are called. The main component behaves as some sort of "wrapper" to call one of the others that have the same interface. The instances of which are injected through the constructor.
Assumptions:
I am using a Social Networking scenario where a main component gets stats on a hastag and instantiates the appropriate Social Sub Component ( There is a Social Component interface:
ISocialComponent
{
SomeStatsObject GetStats(string hashTag);
}
Social Sub-Components implement ISocialComponent Interface
Twitter Sub-Component
public class TwitterSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Twitter-specific code goes here
}
}
Facebook Sub-Component
public class FacebookSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hashTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Facebook-specific code goes here
}
}
Instagram Sub-Component
public class InstagramSubComponent : ISocialComponent
{
public SomeStatsObject GetStats(string hashTag)
{
return SomeMethodThatReturnsStatsObject(hasTag);
}
private SomeMethodThatReturnsStatsObject(string hashTag)
{
//... Instagram-specific code goes here
}
}
Main Component
There is a main social component object that calls any one of the Sub-Components (defined below) that implement the shared ISocialComponent interface
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
//the SocialComponent instance is injected outside of this class
private readonly ISocialComponent _socialComponent;
public MainSocialComponent(ISocialComponent socialComponent)
{
_socialComponent = socialComponent;
}
public SomeStatsObject GetStats(string hashTag)
{
return _socialComponent.GetStats(hashTag)
/**** original code, kept for historical purposes****
switch(_requestedNetwork)
{
case RequestedNetwork.Twitter:
var twit = new TwitterSubComponent();
return twit.GetStats(hashTag)
break;
case RequestedNetwork.Facebook:
var fb = new FacebookSubComponent();
return fb.GetStats(hashTag)
break;
case RequestedNetwork.Instagram:
var in = new InstagramSubComponent();
return in.GetStats(hashTag)
break;
default:
throw new Exception("Undefined Social Network");
break;
}*/
}
}
Updates:
I see why some say it is Factory pattern because it is creating objects. I had mentioned that we use an IoC container and DR. It was my mistake to exclude that. I have refactored the code
Upvotes: 0
Views: 156
Reputation: 636
As others have mentioned, this is part of the Factory/Service pattern which is pretty popular for Dependency Injection and Inversion of Control.
Right now though there is no reason to declare your sub components as non static, since you aren't saving your instances to anything.
So it seems to me unless you have missing code where you add the components to a list or something, you could just do this:
public static class InstagramSubComponent : ISocialComponent
{
public static SomeStatsObject GetStats(string hashTag)
{
return stuff;
}
}
public class MainSocialComponent : ISocialComponent
{
//this is an enum
private RequestedNetwork _requestedNetwork{ get; set;}
private static var Mappings = new Dictionary<string, Func<SomeStatsObject>> {
{ "Twitter", TwitterSubComponent.GetStats },
{ "Facebook", FacebookSubComponent.GetStats },
{ "Instagram", InstagramSubComponent.GetStats }
}
public SomeStatsObject GetStats(string hashTag)
{
return Mappings[hashTag].invoke();
}
}
}
Now if you are doing stuff like actually saving your instances of sub components to a list for later or whatever, then that changes everything. But I am not seeing that so there's no reason not to just make it all static if these methods are simple.
If they are very complex then you'll want to use dependency injection so you can unit test everything proper.
Upvotes: 1
Reputation: 98
This is definitely not an adapter pattern.
An adapter pattern does the following in most cases :
• Works as a bridge between two incompatible interfaces.
• Allows classes with incompatible interfaces work together
Your case is more like a Factory pattern. You use high level abstraction and return the type of interface/component whenever you need to.
Upvotes: 0
Reputation: 77
I believe you can extract creation of SubComponent
into a Factory
and pass this Factory
to MainSocialComponent
. Inside of the GetStats
method, you will call _factory.Create(hashTag);
and than call GetStats
on the returned object.
This way you'll have factory pattern.
Upvotes: 0