Хорошо ли создавать подкласс класса только для разделения некоторых функциональных частей? - PullRequest
2 голосов
/ 25 марта 2010

Предположим, у нас есть абстрактный класс A (все примеры в C #)

public abstract class A
{
    private Foo foo;

    public A() { }

    public void DoSomethingUsingFoo()
    {
        //stuff
    }

    public void DoSomethingElseUsingFoo()
    {
        //stuff
    }

    //a lot of other stuff...
}

Но мы можем разделить его на два класса 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 очень важна.

Разве все же хорошо иметь два отдельных класса только для того, чтобы разделить некоторый код на две части и разделить функциональные элементы?

Ответы [ 7 ]

2 голосов
/ 26 марта 2010

Для меня ваше наследование не имеет смысла повторное использование кода и полиморфизм. Наследование не предназначено для использования исключительно для разделения большого фрагмента кода на две части просто для удобства чтения. Введение дополнительного слоя приносит больше сложностей, чем прояснения, поэтому я не думаю, что это то, что вы должны здесь делать.

Я бы посоветовал вам оставить класс А таким, какой он есть, и позже, когда вы найдете более вескую причину для рефакторинга, вы сделаете это тогда. В этот момент я также согласен с Марком, что вы должны рассматривать композицию, а не наследование.

2 голосов
/ 25 марта 2010

Это хорошая идея, если есть цель введения дополнительной иерархии объектов. В большинстве случаев нет.

В общем, вы должны отдавать предпочтение композиции, а не наследованию . Шаблон Стратегия может быть очень полезным в этом отношении.

0 голосов
/ 06 июля 2010

Ответчик нет.

Чтобы выполнить этот тип разделения кода, разработчик должен использовать частичное ключевое слово для класса, структуры или интерфейса и сохранить их в отдельном файле.

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
}

Использование частичного класса

Начиная с .NET 3.0 можно также создавать частичные методы.

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
}

* Частичные методы не могут иметь модификаторы доступа, такие как public, private или internal.

Использование частичных методов

0 голосов
/ 29 мая 2010

С точки зрения дизайна, ни один класс не является более или менее важным, чем другой класс. Важно то, насколько точно ваша разработанная система программирования отображает реальную систему. Например, если вы хотите запрограммировать человеческое тело в файтинге, любая часть человеческого тела, которую вы хотите запрограммировать, должна быть отдельным классом (например, не потому, что ноготь никогда не используется в бою, это неважный класс, предположим, Вы хотите иметь класс ногтя). Разумеется, один класс может содержать другой класс (т. Е. Один класс является экземпляром другого класса), и те методы функций, которые предоставляют несанкционированную реализацию, могут быть реализованы в классе Util (т. Е. Класс Debug содержит методы, связанные с отладкой). *

Конструкция, которая точно отображает реальную систему, обеспечивает не только преимущества программирования, но и преимущества архитектуры, такие как гибкость и расширяемость.

0 голосов
/ 02 апреля 2010

Поскольку вы говорите, что функциональность в B очень важна, возможно, ей нужен собственный класс. Тогда вы можете иметь B как часть A (составление по наследству, как предложил Марк). Это также может позволить вам более легко тестировать функциональность в B без необходимости создания A. Конечно, это зависит от того, насколько методы в B используют / злоупотребляют данными / методами в A. Может быть, эти данные / методы подойдут лучше в B, а также. Если B не имеет своего собственного веса как отдельный класс, я бы оставил его без изменений.

0 голосов
/ 26 марта 2010

Единственная причина, по которой я бы выделил некоторые функциональные возможности в качестве отдельного класса, заключается в том, что этот набор функциональных возможностей достаточно многократно используется, чтобы вы могли устранить дублирование в другом месте и получить хороший чистый интерфейс, который поддерживает оба варианта использования. В противном случае вы рискуете представить сильно связанные объекты, с которыми сопровождающим может быть сложно работать.

0 голосов
/ 26 марта 2010

Я бы не разделил класс на две части. Основными причинами являются

(а) Вы уверены, что А на самом деле не имеет независимого существования в домене.

(b) Ранняя оптимизация проекта, как правило, является ошибкой - будет достаточно легко провести рефакторинг позже, если выпадет шанс 0,01%.


Не парься по мелочам

Вы, очевидно, продумали это, так что следуйте своим инстинктам.

...