Re: Class design issue

Discussion in 'C++' started by Nilone, Mar 3, 2011.

  1. Nilone

    Nilone Guest

    On Mar 3, 4:21 pm, "crea" <> wrote:
    > Victor Bazarov wrote:
    > > On 3/3/2011 7:43 AM, crea wrote:
    > >> Lets say we are programming a wheather data analysing and display
    > >> program (of course using VC!).

    >
    > >> We have already classes:
    > >> - CChart, which draws wheather data
    > >> - CWheather, which contains wheather data and all the functions
    > >> regarding analysing data. So this data (it contains the data) can be
    > >> passed to CChart to draw it.

    >
    > > BTW, the English word 'weather' does not have the 'h' following 'w'...

    >
    > >> Now we want combine these two to draw a chart with data in it. Is it
    > >> better to create a new class which inherits from them like this:

    >
    > >> 1)
    > >> class CWheatherChart : public CChart, public CWheather
    > >> {
    > >> ...
    > >> };

    >
    > >> or create a class which inludes them as members like this:

    >
    > >> 2)
    > >> class CWheatherChart
    > >> {
    > >>       CChart m_Chart;
    > >>       CWheather m_Wheather;
    > >> ...
    > >> };

    >
    > >> (The point is, that later on we can create specific classes for
    > >> example to moon-wheather , earth wheather, summer wheather... etc.
    > >> which are inherited from CWheatherChart:

    >
    > >> class CMoonWheatherChart : public CWheatherChart)

    >
    > >> These two classes must communicate with eatch others sometimes as
    > >> doing steps,  like when the chart draws a certain data value (x,y)
    > >> it might ask something from CWheather class in the middle of its
    > >> drawing. So using the design 1) we could use virtual functions to
    > >> handle this (having virtual function for data draw in CChart and
    > >> then have also it on CWheatherChart ).

    >
    > >> Which way is better? I guess 1) makes things a bit easier to program
    > >> (can use virtual functions to communicate between CChart and
    > >> CWheather ), but on the other hand 2) gives possibility to change
    > >> easily chart or data on the fly.

    >
    > > First off, both 1) and 2) provide the changeability of 'CChart' and
    > > 'CWheather' part, since, technically speaking, they are contained
    > > within your 'CWheatherChart' in either case.

    >
    > > Public inheritance has the additional perk - the possibility to use
    > > your derived class where the base class is expected - LSP (look it
    > > up).  The containment does not have that.

    >
    > So you think inheritance here might be better?
    >
    >
    >
    > > You have not provided any detailed explanation on how your classes are
    > > going to be used, and *only that* should drive the design.

    >
    > The other one draws the data and the other one contains the data and have
    > all the algorithms.
    >
    > there is nothing special really... The important thing is that as the chart
    > is drawing each individual value to the chart using data, at that moment
    > they must communicate with each others on eatch drawing step. So I kind of
    > think that inheritance meybe better.


    As Victor said, you don't provide much to go on. Basically, you have
    a weather model and a view of it.

    I would make a Weather abstract base class, and derive EarthWeather
    (and later MoonWeather, etc) classes from it. I would make a
    WeatherChart class that accepts a Weather object in its constructor, a
    setter method or its Draw method, depending on its requirements. If
    there's a generic Chart class that's suitable, I would have
    WeatherChart create an instance of it and delegate to it.
     
    Nilone, Mar 3, 2011
    #1
    1. Advertising

  2. Nilone

    James Kanze Guest

    On Mar 3, 6:55 pm, Nilone <> wrote:
    > On Mar 3, 4:21 pm, "crea" <> wrote:


    [...]
    > As Victor said, you don't provide much to go on. Basically, you have
    > a weather model and a view of it.


    > I would make a Weather abstract base class, and derive EarthWeather
    > (and later MoonWeather, etc) classes from it. I would make a
    > WeatherChart class that accepts a Weather object in its constructor, a
    > setter method or its Draw method, depending on its requirements. If
    > there's a generic Chart class that's suitable, I would have
    > WeatherChart create an instance of it and delegate to it.


    More generally, he might read up on MVC.

    Also, these look like entity classes (at least in your view of
    it, which seems like a good starting point). In which case,
    they probably shouldn't be copiable and assignable. And should
    be polymorphic. All of which argues in favor of using pointers,
    rather than direct containment.

    --
    James Kanze
     
    James Kanze, Mar 3, 2011
    #2
    1. Advertising

  3. Nilone

    Nilone Guest

    On Mar 3, 9:11 pm, James Kanze <> wrote:
    > On Mar 3, 6:55 pm, Nilone <> wrote:
    >
    > > On Mar 3, 4:21 pm, "crea" <> wrote:

    >
    >     [...]
    >
    > > As Victor said, you don't provide much to go on.  Basically, you have
    > > a weather model and a view of it.
    > > I would make a Weather abstract base class, and derive EarthWeather
    > > (and later MoonWeather, etc) classes from it.  I would make a
    > > WeatherChart class that accepts a Weather object in its constructor, a
    > > setter method or its Draw method, depending on its requirements.  If
    > > there's a generic Chart class that's suitable, I would have
    > > WeatherChart create an instance of it and delegate to it.

    >
    > More generally, he might read up on MVC.
    >
    > Also, these look like entity classes (at least in your view of
    > it, which seems like a good starting point).  In which case,
    > they probably shouldn't be copiable and assignable.  And should
    > be polymorphic.  All of which argues in favor of using pointers,
    > rather than direct containment.
    >
    > --
    > James Kanze


    Agreed, thanks for the clarification.
     
    Nilone, Mar 3, 2011
    #3
  4. Nilone

    crea Guest

    Nilone wrote:
    > On Mar 3, 4:21 pm, "crea" <> wrote:
    > I would make a Weather abstract base class, and derive EarthWeather
    > (and later MoonWeather, etc) classes from it. I would make a
    > WeatherChart class that accepts a Weather object in its constructor, a
    > setter method or its Draw method, depending on its requirements. If
    > there's a generic Chart class that's suitable, I would have
    > WeatherChart create an instance of it and delegate to it.


    Yes, this is what I wanted, a suggestion. I will think about this... I have
    a real application with similar problem right now...
     
    crea, Mar 3, 2011
    #4
  5. Nilone

    crea Guest

    James Kanze wrote:
    > On Mar 3, 6:55 pm, Nilone <> wrote:
    >> On Mar 3, 4:21 pm, "crea" <> wrote:

    >
    > [...]
    >> As Victor said, you don't provide much to go on. Basically, you have
    >> a weather model and a view of it.

    >
    >> I would make a Weather abstract base class, and derive EarthWeather
    >> (and later MoonWeather, etc) classes from it. I would make a
    >> WeatherChart class that accepts a Weather object in its constructor,
    >> a setter method or its Draw method, depending on its requirements.
    >> If there's a generic Chart class that's suitable, I would have
    >> WeatherChart create an instance of it and delegate to it.

    >
    > More generally, he might read up on MVC.
    >
    > Also, these look like entity classes (at least in your view of
    > it, which seems like a good starting point). In which case,
    > they probably shouldn't be copiable and assignable. And should
    > be polymorphic. All of which argues in favor of using pointers,
    > rather than direct containment.


    Would you pass the windows pointer to Chart -class (to save it by a
    constructor) to be used for all its drawings, or always pass the drawing
    device context (CDC * in VC++) pointer when drawing needs to be done? I
    have been doing the latter normally..
     
    crea, Mar 3, 2011
    #5
  6. Nilone

    crea Guest

    James Kanze wrote:
    > On Mar 3, 6:55 pm, Nilone <> wrote:
    >> On Mar 3, 4:21 pm, "crea" <> wrote:

    >
    > [...]
    >> As Victor said, you don't provide much to go on. Basically, you have
    >> a weather model and a view of it.

    >
    >> I would make a Weather abstract base class, and derive EarthWeather
    >> (and later MoonWeather, etc) classes from it. I would make a
    >> WeatherChart class that accepts a Weather object in its constructor,
    >> a setter method or its Draw method, depending on its requirements.
    >> If there's a generic Chart class that's suitable, I would have
    >> WeatherChart create an instance of it and delegate to it.

    >
    > More generally, he might read up on MVC.


    hmmm, I never seen this before :).
    http://www.tonymarston.net/php-mysql/model-view-controller.html

    So In my case this means, that the weather class really changes the
    view/window. Not vice verse. This is what I was thinking.. So if I handle
    lets say the tenth data of weather, then I take it from weather class and
    set index *there* so that it knows I am using 10th data. Then I update the
    view. So the view does not hold the information that what member I am
    handling. Its the data-classes responsibility.
     
    crea, Mar 3, 2011
    #6
  7. Nilone

    crea Guest

    So Is this what you mean?

    //Generic class Weather
    class Weather
    {..}

    // class for earth derived from Weather
    class EarthWeather : public Weather
    {..}

    // Generic chart class
    class Chart
    {..}

    // class for drawing earth charts
    class EarthChart : public Chart
    {..}

    And then we will create a class to combine these two things: data and
    view/drawing. This class handles their relationship:

    class EarthWeatherView
    {
    EarthChart chart;
    EarthWeather data;
    }

    Then on construction we will pass pointers to both classes possibly like
    this:
    EarthWeatherView::EarthWeatherView()
    {
    chart.AttachData(&data);
    data.AttachChart(&chart);
    }

    Now they can communicate in all directions. Not sure is both attach needed
    though... but the idea is there anyway...

    Now, in real view/window class we can create EarthWeatherView object:
    class CMyView
    {
    EarthWeatherView earthW;
    }
    set data:
    earthW.ReadData(...);

    draw /update view/window:
    OnDraw(CDC* p)
    {
    earthW.Draw(p);
    }

    Correct?


    James Kanze wrote:
    >
    > Also, these look like entity classes (at least in your view of
    > it, which seems like a good starting point). In which case,
    > they probably shouldn't be copiable and assignable. And should
    > be polymorphic. All of which argues in favor of using pointers,
    > rather than direct containment.
     
    crea, Mar 3, 2011
    #7
  8. Nilone

    Nilone Guest

    On Mar 4, 1:39 am, "crea" <> wrote:
    > So Is this what you mean?
    >
    > //Generic class Weather
    > class Weather
    > {..}
    >
    > // class for earth derived from Weather
    > class EarthWeather : public  Weather
    > {..}
    >
    > // Generic chart class
    > class Chart
    > {..}
    >
    > // class for drawing earth charts
    > class EarthChart : public Chart
    > {..}
    >
    > And then we will create a class to combine these two things: data and
    > view/drawing. This class handles their relationship:
    >
    > class EarthWeatherView
    > {
    > EarthChart chart;
    > EarthWeather data;
    >
    > }
    >
    > Then on construction we will pass pointers to both classes possibly like
    > this:
    > EarthWeatherView::EarthWeatherView()
    > {
    > chart.AttachData(&data);
    > data.AttachChart(&chart);
    >
    > }
    >
    > Now they can communicate in all directions. Not sure is both attach needed
    > though... but the idea is there anyway...
    >
    > Now, in real view/window class we can create EarthWeatherView object:
    > class CMyView
    > {
    > EarthWeatherView earthW;}
    >
    > set data:
    > earthW.ReadData(...);
    >
    > draw /update view/window:
    > OnDraw(CDC* p)
    > {
    >     earthW.Draw(p);
    >
    > }
    >
    > Correct?



    That's not quite what I had in mind.

    The Weather class and its derivatives, which is your model, defines
    the concept of weather in the system. It knows weather only, nothing
    else. It can raise events to signal change.

    The WeatherChart class presents information about the model. It gets
    an object derived from Weather passed to it as a parameter, and it
    inspects the model via that interface to determine what to display.
    If it holds on to a Weather object, it can respond to changes.

    You may need a controller class too. The Weather classes hold state
    and have inspection methods, but it's not an actor in the system, it's
    information that gets passed around. You may need to manipulate a
    weather model, or initiate actions based on its data. Such would be
    the work of the controller.
     
    Nilone, Mar 4, 2011
    #8
  9. Nilone

    Paul Guest

    "crea" <> wrote in message
    news:zZUbp.34357$2...
    > Nilone wrote:
    >> On Mar 3, 4:21 pm, "crea" <> wrote:
    >> I would make a Weather abstract base class, and derive EarthWeather
    >> (and later MoonWeather, etc) classes from it. I would make a
    >> WeatherChart class that accepts a Weather object in its constructor, a
    >> setter method or its Draw method, depending on its requirements. If
    >> there's a generic Chart class that's suitable, I would have
    >> WeatherChart create an instance of it and delegate to it.

    >
    > Yes, this is what I wanted, a suggestion. I will think about this... I
    > have a real application with similar problem right now...
    >

    I think your weather class design is good with a base weather and derived
    weather classes:

    But I think you should keep your chart drawing class seperate and consider
    it an extension to the drawing API.
    Wthr_chart I presume is full of lots of good GDI code for drawing the chart,
    labels , axes, titles, etc. You need a system to transfer the data from a
    weather object to the chart. For example your temperature scale maybe min=0,
    max=100 for the earth but on venus its different. You can't just plug the
    data directly into a chart without some meta data.
    You also have timescale, is your weather updated with live transducer data
    or is it user data input? Is it reasonable to have one Weather object per
    month or per year?

    Ok now consider only windspeed data you need something like this:

    class windspeed{
    int max_windspeed, min_windspeed; /*for min/max scale on graph*/
    std::vector<float> windspeed_data;
    std::string name;/*"windspeed" */
    /*need some kind of date metadata, that is related to your data collection
    times.*/
    };

    Now change this to be a generic weather class:
    class WthrData{
    int max, int min;
    std::vector<float> _data;
    std::string name;
    /*some time/date structure*/
    getDateLimits();
    setDateLimits();
    appendData();
    etc etc;
    };

    AmazonWthr{
    WthrData windspeed;
    WthrData humidity;
    WthrData humidity;
    WthrData humidity;
    ....
    };
    VenusWthr{
    WthrData windspeed;
    WthrData humidity;
    WthrData humidity;
    WthrData humidity;
    ....
    };

    Ok so say you want to graph the weather for July-Oct of a particular year,
    how do you select that data? Is the data collected on a daily basis or maybe
    4 times a day?
    You can't just pass the whole weather object and except the drawing class to
    sort it out can you.

    So presumably you will have something like:
    Wthr_Chart::loadData( int MAX, int MIN, std::vector<float> data ,
    std::string name, ??? datelimits );

    VenusWthr v1;
    Wthr_Chart chart1;

    chart1.loadData(v1.windspeed.getMax(), v1.windspeed.getMin(),
    v1.windspeed.getData() , v1.windspeed.getName(),
    v1.windspeed.getDateLimits() /*pass data for line 1*/)
    chart1.loadData(v1.humidity.getMax(), v1.humidity.getMin(),
    v1.humidity.getData() , v1.humidity.getName(), v1.humidity.getDateLimits()
    /*pass data for line 2*/)
    chart1.Draw(HORIZONTAL_LINE_CHART);

    The other way is a reversal of this but requires some interfase logic to get
    the data, and meta data, into a format acceptable for the graphing
    functions. As you were speaking of passing a base pointer to some
    intermediate class, I cannot really go into details without know more about
    the project, but that type of logic seems like a typical case DLL
    ..

    HTH.
     
    Paul, Mar 5, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,952
    Thomas Weidenfeller
    Oct 12, 2005
  2. Jacek Dziedzic
    Replies:
    2
    Views:
    338
    Jakob Bieling
    Oct 17, 2003
  3. John_Woo

    class design vs. db design

    John_Woo, Dec 19, 2006, in forum: Java
    Replies:
    2
    Views:
    356
    John_Woo
    Dec 19, 2006
  4. Bartholomew Simpson

    class design/ design pattern question

    Bartholomew Simpson, Jun 12, 2007, in forum: C++
    Replies:
    2
    Views:
    465
    Daniel T.
    Jun 12, 2007
  5. crea

    Class design issue

    crea, Mar 3, 2011, in forum: C++
    Replies:
    26
    Views:
    636
    Nick Keighley
    Mar 6, 2011
Loading...

Share This Page