I have a class called Person with a property that specifies if there is a Grid object attached. There are 3 types of grid objects. 2 of them will have the exact same properties and the 3rd will have completely different ones.
What is the best type of abstraction to use so the Grid property in the Person class can accept all 3 types? By that I mean should I use an abstract class, 开发者_如何转开发base class, or interface? Or should I look into generics?
My thoughts are to use an abstract class, this way I can implement the properties and not have redundant code in the 2 classes that share the same properties. It will also force anyone adding new grid types to create a new class that is derived from it. I need this last part because I need to check which type of Grid object it is, using reflection, so I can add some conditional logic.
It just feels odd that the 3rd grid type will have these unnecessary properties.
If the 3rd grid type has totally different properties then how can Person accept them all in the same way? You can only 'abstract' commonalities. You are passing 2 different things to Person - so I wouldn't try to abstract them just because they are both grids.
What's wrong with an interface that covers all three Grid types, and an abstract class that implements the interface and covers the things common to the first two?
I would define an interface, which would be common to all 3 grid types.
public interface IGrid
{
// define your Grid contract here
}
I would then create an abstract base class, which defined the things common to the first two types of Grid:
public abstract class GridBase : IGrid
{
}
And derive my two common grids from here:
public class GridTypeA : GridBase { }
public class GridTypeB : GridBase { }
Finally, my 3rd (but totally different Grid), comes from IGrid
public class ObtuseGridType : IGrid
{
}
Now, my person object just has an IGrid.
Don't know why you need to use reflection to get a type of the grid. If you write something like this, a pseudocode:
public abstract class BaseGrid {
...
...
public abstract Type GetGridType();
}
public class Grid1 : BaseGrid {
...
...
public override Type GetGridType() {
return typeof(Grid1 );
}
}
public class Grid2 : BaseGrid {
...
...
public override Type GetGridType() {
return typeof(Grid2 );
}
}
You have a GetGridType()
and don't need a relfection. The return value of that function can be any identifier you prefer based on your app design, not obviously Type.
Regards.
I can't help but think that you've got bigger problems here. Suppose it's possible to have a Person object that can contain one of two entirely different objects. All of your code will read like this:
if (grid is GridTypeA) {
// do some stuff with type a
} else {
// do some stuff with type b
}
That's precisely the kind of switching on types that object orientation is supposed to eliminate. I'd look at the larger design and see if I could improve that. For instance, why does a Person class contain a Grid pointer? Speaking as a person - presumably what you're trying to model - I don't have a grid.
My first question for you would be why the Person object needs to know about the grid - that sounds to me very much like you are allowing your domain level objects to take in external concerns - possibly ui for the grid or some sort of data storage concern.
Second question would be (as everyone else says) is there really any cause for abstraction with these three concepts of grid? Sounds like they are very different things.
That said, the two patterns I would look at if I were you would be Visitor and Strategy.
Both these patterns will allow you to abstract away the concrete implementation details of the grids and their relation to the Person.
精彩评论