Более чистый способ абстракции - PullRequest
2 голосов
/ 28 марта 2011

Я рефакторинг некоторого старого кода и поражен в связи с дизайнерским решением

AbstractClassA
-Step 1
-Step 2
--Step 2.1
--Step 2.2
-Step 3

Вышеупомянутый абстрактный класс имеет абстрактные методы Шаг 1, Шаг 2 и Шаг 3. Шаг 2 всегда должен вызывать методы 2.1 и 2.2. Но в текущем проекте шаги 2.1 и 2.2 не объявлены как абстрактные и были реализованы и вызваны в каждом унаследованном классе. Я планирую провести рефакторинг кода, используя все эти методы (включая 2.1 и 2.2) в интерфейсе. Затем я планирую реализовать реализацию абстрактного класса для этого интерфейса, в которой шаг 2 будет вызывать 2.1 и 2.2. Но так или иначе это не кажется опрятным. Я хочу знать, если этот дизайн имеет недостатки?

InterfaceA
-Step1
-Step2
-Step 2.1
-Step 2.2
-Step3

Ответы [ 4 ]

1 голос
/ 28 марта 2011

Звучит так, как будто вы ищете:

interface IMyInterface
{
    void Step1();
    void Step2();
    void Step3();
}

abstract class MyBaseClass : IMyInterface
{
    public abstract void Step1();
    public void Step2()
    {
        Step2_1();
        Step2_2();
    }
    public abstract void Step3();

    protected abstract void Step2_1();
    protected abstract void Step2_2();
}

Используйте интерфейс для абстракции, когда вы хотите сослаться на что-то общее, где может измениться точный экземпляр, который будет использоваться во время выполнения. Используйте базовый класс для совместной реализации, чтобы вы могли определить, что происходит на шаге 2.1 и шаге 2.2 в каждом подклассе, но ваш базовый класс определяет, что шаг2 означает выполнение шага 2.1, а затем шага 2.2.

0 голосов
/ 28 марта 2011

Ну, вам нужен интерфейс, или вы просто думаете, что делаете?

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

0 голосов
/ 28 марта 2011

Таким образом, кажется, что Step2 является частью интерфейса - что абоненты этого класса ожидают, что смогут вызвать Step2.Но то, что Step2.1 и Step2.2 являются деталями реализации, то, что вы не хотите, чтобы вызывающие видели, хотя это будет реализовано всеми реализаторами интерфейса - я правильно понял?

Если так, то я бы включил в интерфейс Step1, Step2 и Step3 (только).Абстрактный класс будет реализовывать Step2 и дополнительно определять защищенные Step2.1 и Step2.2, но определять их как абстрактные, тем самым вынуждая подклассы предоставлять реализации.

Если вы не подразумевали, что Step2.1 и Step2.2 идентичныво всех подклассах, в этом случае я бы сделал их закрытыми и поместил их в абстрактный класс.

0 голосов
/ 28 марта 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...