简体   繁体   中英

What design pattern is this? Adapter?

[ 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 :

  1. For simplicity, we will ignore DR/IoC for now, but we understand and apply the pattern/principle.
  2. The code is not the best implemented form...feel free to suggest.
  3. My use of the words main/sub does not infer some kind of inheritence...just bad naming on my part, if confusing.
  4. It's language-agnostic, because I love contributions from C# and Java guys, and the knowledge they share.

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM