Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 将一个类划分为子类只是为了分离一些功能部分好吗?_Oop_Class Design - Fatal编程技术网

Oop 将一个类划分为子类只是为了分离一些功能部分好吗?

Oop 将一个类划分为子类只是为了分离一些功能部分好吗?,oop,class-design,Oop,Class Design,假设我们有一个抽象类A(所有例子都在C#中) 但我们可以将其分为两类A和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() { //stu

假设我们有一个抽象类
A
(所有例子都在C#中)

但我们可以将其分为两类
A
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()
    {
        //stuff
    }

    public void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //nothing else or just some overrides of A stuff
}
这很好,但我们99.99%确信,没有人会将
A
子类化,因为
B
中的功能非常重要


有两个单独的类,只将一些代码分成两部分,并将功能元素分开,这样做是否仍然好?

只有在引入额外的对象层次结构的情况下,这样做才是一个好主意。大多数时候,没有

一般来说,你应该喜欢组合而不是继承。在这方面,设计模式非常有用。

我不会将类一分为二。主要原因是,

(a) 你肯定a在域中没有真正独立的存在

(b) 早期的设计优化通常是一个错误——如果出现0.01%的机会,那么以后重构就很容易了


不要为小事操心
你显然已经想清楚了,所以还是凭直觉去做吧。

对我来说,你的继承没有任何代码重用和多态性的目的。继承并不意味着仅仅为了便于阅读而将一大块代码分成两部分。额外层的引入带来了比清晰化更多的复杂性,所以我认为这不是您应该在这里做的事情


我建议您保持类A的原样,以后当您找到更有力的理由进行重构时,您就可以进行重构了。在那一刻,我也同意马克,你应该考虑合成而不是继承。

唯一的原因是我将一些功能分开作为一个单独的类,当这个功能块被重复使用时,你可以在其他地方消除重复,并且你可以得到一个良好的干净的界面来支持这两种用途。否则,您可能会引入高耦合的对象,这对维护人员来说很难使用。

既然您说B中的功能非常重要,那么它可能需要自己的类。然后你可以把B作为a的一部分(如马克所建议的,组合优先于继承)。这还可以让您更轻松地测试B中的功能,而无需创建A。当然,这取决于B中的方法在多大程度上使用/滥用A中的数据/方法。也许这些数据/方法也更适合B。如果B不作为一个单独的类来承载它自己的重量,那么我会让它保持原样。

从设计的角度来看,没有一个类比另一个类更重要或更不重要。重要的是您设计的编程系统映射真实系统的准确性。例如,如果你想在格斗游戏中对人体进行编程,那么你想编程的人体的任何部分都应该是一个单独的类(例如,不是因为在格斗中从未使用过fingernail,而是一个不重要的类,假设你想拥有fingernail类)。当然,一个类可以包含另一个类(即,一个类是该类的一个实例),并且那些提供图的函数方法可以在Util类中实现(即,调试类包含与调试相关的方法)

准确映射真实系统的设计不仅提供了编程优势,还提供了架构优势,如灵活性和可扩展性。

anwser不是

为了完成这种类型的代码分离,开发人员应该为类、结构或接口使用partial关键字,并将它们存储在单独的文件中

逻辑类

public partial class A
{
    public A() { }

    //a lot of stuff...
}
public abstract class A
{
    public A() { }

    partial void DoSomethingUsingFoo();
    partial void DoSomethingElseUsingFoo();


    //a lot of stuff...
}
教职员班

public partial class A
{
    private Foo foo;

    public void DoSomethingUsingFoo()
    {
        //stuff
    }

    public void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //nothing else or just some overrides of A stuff
}
public abstract class A
{
    private Foo foo;

    partial void DoSomethingUsingFoo()
    {
        //stuff
    }

    partial void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //nothing else or just some overrides of A stuff
}

由于.NET3.0,还可以创建分部方法

逻辑类

public partial class A
{
    public A() { }

    //a lot of stuff...
}
public abstract class A
{
    public A() { }

    partial void DoSomethingUsingFoo();
    partial void DoSomethingElseUsingFoo();


    //a lot of stuff...
}
教职员班

public partial class A
{
    private Foo foo;

    public void DoSomethingUsingFoo()
    {
        //stuff
    }

    public void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //nothing else or just some overrides of A stuff
}
public abstract class A
{
    private Foo foo;

    partial void DoSomethingUsingFoo()
    {
        //stuff
    }

    partial void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //nothing else or just some overrides of A stuff
}
*分部方法不能具有访问修饰符,如public、private或internal