问题
I've got a class that I want to extend functionality to in a decorator/adapter kind of a way, only I don't want my extending class to have to know anything about the kinds of classes it is extending, and I don't want to have to write a new class for each type of object I want to extend. All objects I would want to extend off of, though, share a common base class, Team
. This sounds ripe for a use of generics, so here was my initial idea:
public class TournamentTeam<T> : T
where T : Team
{
private int mSeed;
public TournamentTeam(T team, int seed)
: base(team)
{
/*
* error checking stuff here
*/
// set class variables
this.mSeed = seed;
}
public int Seed
{
get { return this.mSeed; }
}
}
This would have done what I wanted, as now if I want to access members of T, the new class has all of them. The base constructor would take care of setting up the state in a way such that the extended class didn't need to worry about it. I also wouldn't have to know what methods to override in order to point to an internal object in a decorator/facade type manner. Needless to say, this didn't compile. So, I tried something a little different.
public class TournamentTeam<T> : Team
where T : Team
{
#region class variables
private int mSeed;
private T mTeam;
#endregion
public TournamentTeam(int seed, T team)
: base(team)
{
/*
* error checking stuff here
*/
// set class variables
this.mSeed = seed;
this.mTeam = team;
}
public int Seed
{
get { return this.mSeed; }
}
public T Team
{
get { return this.mTeam; }
}
}
OK, now if I want to get at the functionality of the "base class", I just call the Team property and I'm good to go. And, since it's generic, I don't have to do any boxing to get to the functionality. it works, it aint pretty, but it works.
What pattern is this, if one exists, and what pitfalls do yall see with this idea? Is there a better way to accomplish this?
回答1:
this is what should be done as I see it "favor composition over inheritance" principal and the "strategy" pattern (if im not mistaken)
I also like the implimentation.
回答2:
It's unfortunate that C# doesn't allow inheritance from type parameters because I think the first design is ideal, given what you want to achieve.
The second design seems like a reasonable application of the adapter pattern, provided that you ensure that all public TournamentTeam members inherited from Team have their invocations redirected towards the encapsulated Team.
Personally, if I were to design this in C#, I'd ditch the adapter pattern in favour of plain composition and do something like the following:
- Rename TournamentTeam to something else... maybe TournamentTeamAllocation or TournamentTeamInfo or something like that (names are hard!). Basically, it'd be responsible for dealing with data related to both a tournament and a team (i.e. seeds)
- Change it so that it doesn't subclass anything
- Keep the encapsulation so that it still contains a
T : Team
.
来源:https://stackoverflow.com/questions/9652693/what-design-pattern-would-this-be-and-is-it-a-good-idea-c