3

I've got several C# classes each with similar properties. (They're part of an SDK and their code can’t be changed.)

  • Person.Name
  • Product.Name
  • Order.Name

I want to use these classes polymorphically, but they don’t implement a common interface or derive from a common base class, so that’s not possible. To get around this, I’d like to wrap each one in another class that does implement a common interface, and wire-up each class property to its corresponding interface property.

What would be a suitable name for the wrapper classes? Wrapper, Decorator, Adaptor, Proxy? Does this pattern have a name? Is there a better approach?

(I don't want to use dynamic duck-typing or an impromptu interface.)

Chris Fulstow
  • 41,170
  • 10
  • 86
  • 110
  • This seems like a subjective question, and you're already calling them 'wrapper' classes. Why not go with that? – Andorbal Feb 18 '13 at 15:23
  • I'd go with *Proxy* personally, since the wrapper class is authorized to act on behalf of the wrappee, i.e. is representative of it. – John Willemse Feb 18 '13 at 15:25
  • 1
    I've implemented this as 'composition' pattern in the framework I'm selling, which is effectively a proxy to all different types with behavior dictating what would happen in case of a name conflict (such as 'Name'). It is of course possible to implement that manually as well... Perhaps that's what you're looking for? – atlaste Feb 27 '13 at 15:37

5 Answers5

4

It looks like Adapter, because you are adapting the existing interfaces to the specific requirements.

Ryszard Dżegan
  • 24,366
  • 6
  • 38
  • 56
  • Adapter doesn't feel quite right to me because I'm not really adapting from one interface to another, rather I'm wrapping the existing same-named properties with a common interface so the classes can be used polymorphically. – Chris Fulstow Feb 18 '13 at 15:30
  • 1
    @ChrisFulstow But that depends on the definition of an interface. In this case the interfaces are the same in terms of exposed members, but different in terms of type hierarchy. – Adam Houldsworth Feb 18 '13 at 15:44
  • 1
    Definition of Adapter: _Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces._. Here, client expects a common interface that not exists. You must create that interface in order to make incompatible classes work together. It matches to the definition I think. – Ryszard Dżegan Feb 18 '13 at 15:47
  • @yBee I agree, it's a close enough match to call it. – Adam Houldsworth Feb 18 '13 at 15:59
3

(I don't want to use dynamic duck-typing or an impromptu interface.)

So what is wrong with a NamedObject?

public class NamedObject
{
    public string Name { get; set; }
}

It literally says what it is, nothing less, nothing more.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
2

I'd stick with CodeCaster's idea, and perhaps with a dash of Func<T> for no other reason than I get withdrawal symptoms when I don't use angle brackets...

public class NamedEntity
{
    public string Name { get { return _getName(); } }

    private Func<string> _getName;

    public NamedObject(Func<string> getName)
    {
        _getName = getName;
    }
}

And then call thus:

var named = new[] 
    { 
        new NamedEntity(() => person.Name),
        new NamedEntity(() => product.Name),
        new NamedEntity(() => order.Name)
    };

The added benefit with this is when the value of the property changes on the target object, it changes within the NamedEntity reference too via the Func, this means within the life span of the objects you can get away with wrapping them once. You can also do the inverse with Funcs that set values as well as get, and can adapt more properties.

I am not immediately sure what pattern this represents (if any), though I would guess Adapter pattern (which is a type of wrapper pattern). However, it could also be argued to be a Proxy pattern. Not sure really.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
1

Maybe you can just change the namespace and keep the names of the original classes.

Z .
  • 12,657
  • 1
  • 31
  • 56
1

Technically, I think the most correct name would be Adapter, see this question.

Adapter is used when you have an abstract interface, and you want to map that interface to another object which has similar functional role, but a different interface.

You don't have abstract interface, but "similar functional role, but a different interface".

Community
  • 1
  • 1
jhexp
  • 685
  • 4
  • 9