简体   繁体   中英

How do you 'adapt' a class member that is a collection?

So I'm trying to create an adapter where the adapter inherits from the class it is trying emulate. The constructor takes an instance of the class that will be adapted and then maps properties so that the two are piping info through each other, pretty standard, i think. However, one of the members happens to be a list of another type that must be adapted as well. Is there a pattern for this??

Here's an example:

public class Contract.ClassA
{
    public List<Contract.ListMemberClass> Members { get; set; }
}

public class Domain.ClassA
{
    public List<Domain.ListMemberClass> Members { get; set; }
}

public class Contract.ListMemberClass
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Domain.ListMemberClass
{
    public string FName { get; set; }
    public string LName { get; set; }
}

// adapters

public class DomainClassAdapter : Domain.ClassA
{
    private readonly Contract.ClassA _input;

    public DomainClassAdapter(Contract.ClassA input)
    {
        _input = input;
    }

    public List<Domain.ListMemberClass> Members {
    {
        get
        {
            // ???
        }
        set
        {
            // ???
        }
    }
}

So my first instinct for the getter is to create yet another adapter for that list member, new that up and return that. And then do the same thing going the other direction for the setter. So I could end up with umpteen billion adapters.

Is that the only way to do this, or is there some other pattern, trick, technology, etc to address this scenario??

It seems reasonable to me that the Domain.ListMemberClass would have an adapter. However, I'm not really aware of any pattern for this.

Assuming you only need to convert between the Domain and Contract namespace when doing a server call, I'd actually suggest putting the behavior in the constructor and leaving the property auto-implemented.

public DomainClassAdapter(Contract.ClassA input)
{
  _input = input;
  this.Members = _input.Members.Select(x => new DomainListMemberAdapter(x));
}

If you don't want to create a bunch of clutter from adapters, it'd be simple enough (especially with just two properties) to create Domain.ListMemberClass instances inside the LINQ statement, instead of adapter instances.

If you don't want to have a constructor call that could be expensive, you could do a cached approach for the property:

private List<Domain.ListMemberClass> _members;
public List<Domain.ListMemberClass> Members {
{
  get
  {
    if(_members == null)
    {
      // Populate _members from _input
    }
    return _members;
  }
  set
  {
    // No special behavior necessary, I think
  }
}

Both examples assume you'd call some method that would convert everything to the Contract namespace models when necessary. I'm a bit afraid I may have missed the point of the adapter pattern though, so please let me know if I have, in fact, missed the point.

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