Is it good to subclass a class only to separate some functional parts?
Suppose we have abstract class A
(all examples in C#)
public abstract class A
{
private Foo foo;
public A() { }
public void DoSomethingUsingFoo()
{
//stuff
}
public void DoSomethingElseUsingFoo()
{
//stuff
}
//a lot of other stuff...
}
But we are able to split it into two classes A
and B
:
public abstract class A
{
public A() { }
//a lot of stuff...
}
public abstract class B : A
{
private Foo foo;
public B() : base() { }
public void DoSomethingUsingFoo()
{
开发者_JS百科//stuff
}
public void DoSomethingElseUsingFoo()
{
//stuff
}
//nothing else or just some overrides of A stuff
}
That's good, but we are 99.99% sure, that no one will ever subclass A
, because functionality in B
is very important.
Is it still good to have two separate classes only to split some code into two parts and to separate functional elements?
To me, your inheritance doesn't serve any purpose of code reuse and polymorphism. Inheritance is not meant to be used solely to split a big piece of code into two places just for easy reading. The introduction of an extra layer brings more complication than clearification so I don't think it is the thing you should do here.
I would suggest you leave class A as what it is and later when you find a stronger reason to refactor, you do it then. At that moment, I also agree with Mark that you should consider composition than inheritance.
It's only a good idea to do this if there is a purpose of introducing an additional object hierarchy. Most of the times, there isn't.
In general, you should favor composition over inheritance. The Strategy design pattern can be very helpful in this regard.
I wouldn't split the class in two. The main reasons being
(a) You're certain that A doesn't really have an independent existence in the domain.
(b) Early optimization of the design is generally a mistake - it'll be easy enough to refactor later if that 0.01% chance happens to come up.
Don't sweat the small things
You've obviously thought it through so go with your gut instincts.
The only reason I would split some functionality off as a separate class is when that chunk of functionality is re-usable enough that you can eliminate duplication somewhere else, and you can get a good clean interface that supports both uses. Otherwise you risk introducing highly coupled objects that can be hard for maintainers to work with.
Since you say functionality in B is very important, maybe it needs its own class. Then you can have B as a part of A (composition over inheritance as Mark suggested). This might also allow you to test the functionality in B more easily without the need for creating A. Of course it depends on how much the methods in B are using/abusing the data/methods in A. Maybe those data/methods would fit better into B as well. If B doesn't carry its own weight as a separate class then I would leave it as it is.
From the design point of view, no class is more or less important than another class. What is important is how accurate your designed programing system maps the real system. For example, if you want to program a human body in a fighting game, any part of the human body you want to program should be an individual class (e.g., not because fingernail is never used in a fight, it's an unimportant class, suppose you want to have a fingernail class). Certainly, one class can contain another class (i.e., one class is an instance of anothe class), and those function methods that provides the infrustrure can be implemented in a Util class (i.e., a Debug class contains debug related methods).
A design that accurately maps the real system provides not only programming benefits, but also architecture benefits such as flexiblity and extensibility.
The anwser is no.
To accomplish this type of code separation, developer should use the partial keyword for class, struct or interface and store them in separate file.
A_logic.class
public partial class A
{
public A() { }
//a lot of stuff...
}
A_staff.class
public partial class A
{
private Foo foo;
public void DoSomethingUsingFoo()
{
//stuff
}
public void DoSomethingElseUsingFoo()
{
//stuff
}
//nothing else or just some overrides of A stuff
}
Usage of Partial Class
Since .NET 3.0 it is possible also to create partial methods.
A_logic.class
public abstract class A
{
public A() { }
partial void DoSomethingUsingFoo();
partial void DoSomethingElseUsingFoo();
//a lot of stuff...
}
A_staff.class
public abstract class A
{
private Foo foo;
partial void DoSomethingUsingFoo()
{
//stuff
}
partial void DoSomethingElseUsingFoo()
{
//stuff
}
//nothing else or just some overrides of A stuff
}
*The partial methods cannot have access modifiers such as public, private or internal.
Usage of Partial Methods
精彩评论