Как мне структурировать иерархию классов, состоящую из разработчиков интерфейсов с детьми? - PullRequest
0 голосов
/ 13 июня 2019

Я работаю над программным обеспечением, которое принимает огромное количество входных данных, а затем автоматически проектирует машины. Сейчас я создаю систему отчетности, которая предоставляет сложные PDF-отчеты о производительности, конструкции и дизайне этого оборудования. Это оборудование имеет ряд отдельных частей, которые имеют ряд стандартных типов (например: деталь "Двигатель", а данный подтип может быть "2 цилиндра"); дизайн все параметрический и подтипы достаточно разные, чтобы заслужить свои собственные классы. Все эти части имеют измерения размеров, и я должен предоставить отчеты в единицах IP и SI. Мне нужны идеи о том, как структурировать иерархию классов, которая имеет смысл и с которой легко работать в остальной части кода, который я напишу. Подвох заключается в пересчете единиц. Некоторые части Механизма являются универсальными и всегда будут существовать и реализовываться одинаково независимо от подкласса, поэтому для него требуются методы преобразования, но другие поля не являются универсальными, поэтому базовые классы также нуждаются в методах преобразования.

Пойдем с примером Engine. Вот что-то вроде того, что у меня есть сейчас. У меня есть базовый абстрактный класс, представляющий Engine, реализующий интерфейс IConvertible, который означает, что деталь может быть преобразована из единиц IP в единицы СИ. Подкласс TwoCylinderEngine наследуется от Engine и переопределяет методы преобразования класса Engine, но не реализует сам IConvertible. Я должен упомянуть, что у меня есть класс Measurement, который обрабатывает преобразования единиц, поэтому реализация этой части не имеет отношения к моей проблеме.

public abstract class Engine : IConvertible {

    Measurement someMeasurement;

    public void ConvertToIP(){
        BaseConvertToIP();
    }

    public void ConvertToSI(){
        BaseConvertToSI();
    }

    public void BaseConvertToIP(){
        someMeasurement = someMeasurement.ConvertTo("some IP Unit");
    }

    public void BaseConvertToSI(){
        someMeasurement = someMeasurement.ConvertTo("some SI Unit");
    }
}

public class TwoCylinderEngine: Engine{

    Measurement someOtherMeasurement;

    public override void ConvertToIP(){
        BaseConvertToIP();
        someOtherMeasurement = someOtherMeasurement.ConvertTo("some IP Unit");
    }

    public override void ConvertToSI(){
        BaseConvertToSI();
        someOtherMeasurement = someOtherMeasurement.ConvertTo("some SI Unit");
    }
}

public interface IConvertible
{
    void ConvertToIP();
    void ConvertToSI();
    void BaseConvertToIP();
    void BaseConvertToSI();
}

Эта конструкция хорошо работает для меня, но меня не устраивает необходимость сделать BaseConvertToIP() и BaseConvertToSI() общедоступными. Я бы хотел, чтобы был способ объявить методы защищенного интерфейса для такого рода обстоятельств, но я понимаю, что это противоречит идее о том, что такое интерфейс в первую очередь. Я не уверен, в какие отношения эта вещь вписывается, насколько ООП идет. Есть идеи?

1 Ответ

0 голосов
/ 14 июня 2019

Извиняюсь за вопрос в первую очередь.Я думал, что попробовал это, но, похоже, нет.У меня возникла проблема с публичным характером BaseConvertTo методов, которые мне не нравились.Решение состоит в том, чтобы вообще не иметь этих методов.Вместо этого просто используйте виртуальные ConvertTo методы в базовом классе, и тогда они могут быть вызваны с base.ConvertTo в производных классах.Это исправляет одну проблему, которая у меня была с иерархией классов.

public abstract class Engine : IConvertible {

    Measurement someMeasurement;

    public virtual void ConvertToIP(){
        someMeasurement.ConvertTo("Some IP Unit");
    }

    public virtual void ConvertToSI(){
        someMeasurement.ConvertTo("Some SI Unit");
    }
}

public class TwoCylinderEngine: Engine{

    Measurement someOtherMeasurement;

    public override void ConvertToIP(){
        base.ConvertToIP();
        someOtherMeasurement = someOtherMeasurement.ConvertTo("some IP Unit");
    }

    public override void ConvertToSI(){
        base.ConvertToSI();
        someOtherMeasurement = someOtherMeasurement.ConvertTo("some SI Unit");
    }
}

public interface IConvertible
{
    void ConvertToIP();
    void ConvertToSI();
}

Это позволяет достичь того, чего я хочу.Название вопроса по-прежнему актуально, я думаю.Просто ответ намного проще, чем я думал.

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