Protected variables and methods


#1

To help us be able to subclass the JUCE classes it would be great if you made all (or more of) your private methods and variables protected… similar to MFC…

For instance to subclass ImageButton to be able to change the images dynamically:

[code]class CImageButtonEx : public ImageButton
{
public:
CImageButtonEx();
~CImageButtonEx();

    void    changeNormalImage(const Image &normalImage_) { normalImage = normalImage_; }
    void    changeDownImage(const Image &downImage_) { downImage = downImage_; }
    void    changeOverImage(const Image &overImage_) { overImage = overImage_; }

};[/code]

I had to change

to protected in juce_ImageButton.h - which I’ll have to do every time the framework is updated…

Thanks,

Rail


#2

Sorry… are you actually serious? This is such a ridiculous thing to ask that I can’t even tell whether it’s actually a very geeky joke… (The mention of MFC as an example of good OO design practice is surely a sign that you’re joking… right??)


#3

You’re giving praise to MFC for its software design?

Well, it’s not the 1st of April…


#4
#define private protected

#5

[quote=“TheVinn”] #define private protected [/quote]


#6

Yes I am being serious… unless you don’t want us to subclass the JUCE classes… Otherwise we need to have methods where we can access some of the private variables which would make sense for us to be able expand the classes… like in my example.

If this were an in-house framework I’d be with you… but the idea is that the framework should be easily expanded upon by the users at large without having to change the underlying code every time they want to subclass something.

This isn’t as ridiculous a request as you’re making it out… how would you recommend the users expand/customize on the library otherwise? We can’t be modiying the JUCE classes to add our changes and have to reapply them to the code every time you update it. The very idea of OO was to be able to reuse the code by subclassing existing classes - and that’s why we have protected members.

I used MFC for many, many years… and while it had many shortcomings it was very simple to use and easy to expand upon. Sometimes you need to step back from perfect code practices for practicality.


http://msdn.microsoft.com/en-us/library/ms229024(v=vs.80).aspx
http://my.safaribooksonline.com/book/programming/microsoft-dotnet/9780321578815/extensibility-mechanisms/ch06lev2sec2

Cheers,

Rail


#7

You know, you could subclass a base-class and setup objects the way you want them (ie: juce::Button)? Nothing stops you from doing that to create your custom ImageButton, for example, as you see fit.


#8

Yes, but then I have to copy ImageButton as my new class and modify that… and if Jules makes any changes to ImageButton I have to find what they are and apply them to my class… whereas if the members were protected all I would have to do would be nothing.

Rail


#9

To be frank, MFC isn’t a basis for good software design decisions… In fact, myself, and most programmers I know, frown upon it because of this very reason.

JUCE is well designed, well thought out, and is very practical. For the sake of it, attempt rethinking the way you create your objects; you may find yourself creating better code. What is it that you are attempting in doing with ImageButton? Changing one image at a time, instead of all of them at once? Try suggesting adding methods for doing such to Jules, and let him ponder and get back to you, and you will see why he hasn’t done that.


#10

What am I trying to achieve… very simple:

For a button to have a different image under certain circumstances… like a mute button when another track is solo’d… the mute (down) button image should be different to the regular mute (down) button image – a simple method to switch the image is fast and easily accomplished by subclassing the ImageButton class.

You’re basically suggesting we never subclass any of the JUCE classes and ask Jules to make changes which may be specific to our application.

I didn’t put MFC up as the holy grail of OO design – heck it doesn’t even have multiple inheritance… I used it as an example of a framework which was easily expanded upon because the developers knew the user base would want to expand upon it.

Rail


#11

That’s not what I’m suggesting at all. You must surely realize that not every class created in JUCE is intended to be subclassed (the same should apply to any library, for that matter). Ever think that there may be a different approach to your problem?


#12

That’s not what I’m suggesting at all. You must surely realize that not every class created in JUCE is intended to be subclassed (the same should apply to any library, for that matter). Ever think that there may be a different approach to your problem?[/quote]

I’m not asking for every class member in JUCE to be changed… just those like in UI which are more likely candidates.

I’m sure I can come up with many alternatives… but this is the fastest method and is built upon existing code… the very principle of OO.

I can change the members in the JUCE header every time I get the latest tip… I was simply asking Jules to consider a small change to assist his user base. I certainly wasn’t trying to get into an idealogical argument.

Rail


#13

The kindest thing I could do for my user base would be to somehow hide all the private details from the header files completely, so there’s no temptation!

Honestly, if I was reviewing someone’s code and saw that they’d hacked a parent class written by someone else so they could mess with a member variable… oh, there’d be some fireworks! That’s a bad 'un. If you don’t understand why it’s a such a coding sin, you probably need to do some reading about good OO design practices and clean your mind of all that MFC crap. I’m sure there are books and tutorials out there that explain this stuff very clearly, but after 20 years of this stuff I just feel deep pain when I hear you asking for more coupling of state between unrelated classes!

And for god’s sake, why not just call ImageButton::setImages()?? It’s shameful enough to do a dirty hack when there’s no alternative, but the ImageButton class lets you do what you need anyway!


#14

Of course I know I could call ImageButton::setImages(), I was looking to reduce the lines of code executed… one line vs. 20+ (and a repaint())

I understand encapsulation… but what I’m trying to achieve would normally be accomplished by adding a new method to the class… I was trying to do that without having to bother you by asking for the method to be added and was looking for a simple methodology to expand upon JUCE without having to do a lot of extra work every time you make changes.

Cheers,

Rail


#15

You have this backwards, I’m afraid.
If it were an in-house framework you could do what you like with it. If you decided that you had to modify the workings of the base class, it’s not so bad since you also have access to the instances of its adoption.
The fact that juce has a huge number of external users means that such restrictions must be in place if Jules wants to retain control over the details of implementation.

To the user, protected is as good as private. To the library maintainer, protected is really no better than public.


#16

You have this backwards, I’m afraid.
If it were an in-house framework you could do what you like with it. If you decided that you had to modify the workings of the base class, it’s not so bad since you also have access to the instances of its adoption.
The fact that juce has a huge number of external users means that such restrictions must be in place if Jules wants to retain control over the details of implementation.

To the user, protected is as good as private. To the library maintainer, protected is really no better than public.[/quote]

And I understand that too… What I’m trying to do is come up with a balance… I’m looking to be able to modify the base class (if necessary) without having a huge maintenance nightmare. I can of course understand Jules’ desire to have us keep our grubby paws off his code. The change I was making in this particular instance to his class via a subclass is benign and IMO safe… and saved me a bunch of extra executed lines of code.

Surely adding the method to the class is far more egregious than subclassing the class and asking for the members to be protected?

Cheers,

Rail