Сценарий объектно-ориентированного проектирования / проектирования - PullRequest
2 голосов
/ 06 января 2012

У меня есть 3 различных типа диаграмм форм, скажем Rectangle, Cube, Circle, я хочу определить классы для них так, чтобы

  • Все классы имели заголовок& Свойство / метод color,

  • У круга и прямоугольника будет дополнительный метод Area,

  • Аналогично, у куба будет метод Volume, а не метод Area.

Есть метод, в котором я получаю ссылку на «объект», ниже приведен пример метода

public void ShapeClicked(object obj)
{
// Check the type of obj & type cast it accordingly & call the method on that object
    object obj = new Circle();

    if (obj is Circle)
    {
        Circle circleObj  = (Circle)obj;
        circleObj.GetArea();
    }
    else if (obj is Rectangle)
    {
        Rectangle rectangleObj = (Rectangle)obj;
        rectangleObj.GetArea();
    }
    else if (obj is Cube)
    {
        Cube cubeObj = (Cube)obj;
        cubeObj.GetVolume();
    }
}

Как я могу спроектировать свои классы так, чтобы вМетод ShapeClicked (object obj)

  • a) Мне не нужно проверять тип каждый раз (должен происходить во время выполнения), (это важно дляменя, потому что у меня есть много методов, таких как 'ShapeClicked', который требует от меня проверки типа)

  • b) если объект имеет тип Circle, то он получит только метод Area,аналогично для объекта Cube он получит только метод Volume.

Я могу представить два подхода

  • Поместить все методы и свойства в базовый класс& переопределяет только необходимые методы в производном классе.Создайте метод / класс Factory, который будет возвращать ссылку на базовый класс.При таком подходе мое требование «b» не удовлетворяет

  • Поместите только базовые методы / свойства (например, цвет) в базовый класс и добавьте дополнительные методы в производный класс.Это не решает #a: (

Может кто-нибудь предложить мне какое-нибудь решение, которое решает как #a & # b

Ответы [ 3 ]

3 голосов
/ 06 января 2012

Введите новый интерфейс.

public interface IMeasurable
{
    someReturnType GetMeasure();
}

public class Circle : IMeasurable
{
    //some other methods

    public someReturnType GetMeasure() { return GetArea(); }
}

public class Cube : IMeasurable
{
    //some other methods

    public someReturnType GetMeasure() { return GetVolume(); }
}

Обновление

Ваш метод будет выглядеть так:

public void ShapeClicked(object obj)
{
    var measurable = obj as IMeasurable;
    if (measurable == null)
        throw new InvalidOperationException(string.Format("We can only work with measurable types, which {0} is not.", obj.GetType());

    var measure = measurable.GetMeasure();
}
0 голосов
/ 06 января 2012

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

В этом случае вы действительно пытаетесь определить общий интерфейс, чтобы вы могли одинаково относиться к своим типам.

Я бы определил следующее:

public interface IShape
{
    string Title { get; }

    string Color { get; }
}

public interface I2DShape : IShape
{
    int GetArea();
}

public interface I3DShape : IShape
{
    int GetVolume();
}

Затем можно реализовать I2DShape в Circle и Rectangle, а также I3DShape в Cube. Ваш метод может быть реализован так:

public void ShapeClicked(IShape shape)
{
    var shape2d = shape as I2DShape;

    if(shape2d != null)
    {
        shape2d.GetArea();
        return;
    }

    var shape3d = shape as I3DShape;

    if(shape3d != null)
    {
        shape3d.GetVolume();
    }
}

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

0 голосов
/ 06 января 2012

Да.

Вы должны иметь базовый класс для всех фигур и иметь метод ShapeClicked() в базовом классе.

class Shape 
{
-tile
-color
ShapeClicked()
}

class PlanarShape extends Shape
{
-area
Area()
}

class SpatialShape extends Shape
{
-volume
Volume()
}

class Circle extends PlanarShape
{
ShapeClicked()
}

class Rectangle extends PlanarShape
{
ShapeClicked()
}

class Cube extends SpatialShape
{
ShapeClicked()
}

Затем вы изменяете функцию следующим образом:

public void ShapeClicked(Shape obj)
{
    obj.ShapeClicked();
}

В результате полиморфизма ваш звонок будет направлен в нужный класс.

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