Developer Zone

Advanced Software Development with MATLAB

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Mix It Up and Mix It In 8

Posted by Andy Campbell,

What can we learn about software from an ice cream shop? Quite a bit apparently. It was in the early 70's that Steve's Ice Cream opened and introduced the world to the notion of mix-ins. The idea was simple but powerful. Lets produce a small amount of base ice cream flavors like vanilla, chocolate, and strawberry. Then, the strategy goes, provide a plethora of small independent ingredients to mix in to the base flavor resulting in unending flavor possibilities.

Given the success of this approach and many many other ice cream shops like Cold Stone Creamery and Diary Queen that provide similar services the approach seems almost obvious. Well, many things seem obvious in retrospect.

The idea itself has great merit! I would want to be able to serve the customer who wants their ice cream to be crunchy as well as those that gag at the thought. If they also want (need!) that smooth caramel ribbon that should be no problem. It is relatively easy to provide 4 different ice cream flavors with different combinations of nuts and caramel to appease all customer types, but this becomes a bit harder when we experience the combinatorial explosion of including (or not!) nuts, oreos, sprinkles, gummy bears, peanut butter cups, and on and on. The genius of the mixin approach is the realization that while each of these items on their own does not an ice cream flavor make, when you can independently choose which of them to mix in for a particular customer the ice cream shop owner can be very nimble to adapt to the needs at hand.

Does this resonate with MATLAB? As we strive to keep MATLAB class hierarchies wide the mixin approach can be very attractive. To apply this approach what we need to do is use the various attributes and capabilities that we want to share across many different types of classes or objects and package them up into their own independent mixin class. Such a mixin class should truly have just one purpose or responsibility. The idea is that this is a class which does not have much meaning on its own, much like a walnut does not have much value as an ice cream product on it own. However, when mixed in with other code can provide a rich, yet flexible, software product.

Technically speaking, we already saw this with our first discussion on this theme of flexible inheritance hierarchies. In this example we see the following code:

classdef CelestialBody
    properties
        Mass
    end
end



classdef(Abstract) Rounded 
    properties
        Radius
    end   
end
    
    



classdef Asteroid < CelestialBody 
    properties
        Shape
    end
end



classdef Moon < CelestialBody & Rounded
    properties
        HostPlanet
    end
end



classdef Star < CelestialBody & Rounded
    methods
        function radiate(star)
        end
    end
end



classdef Planet < CelestialBody & Rounded
    properties
        Moons
    end
end



classdef TerrestrialPlanet < Planet
    properties
        Crust
    end    
end



classdef(Abstract) HasRings
    properties
        Rings
    end
end



classdef GasGiant < Planet & HasRings
end



classdef IceGiant < Planet & HasRings
end

This code produces the wide hierarchy below:

What we didn't really discuss last time was that this is actually inheriting not just interface, but actually implementation from the Rounded and HasRings base classes. This is an alternative to composition which brings both the interface and the implementation to the inheriting class. The key to success here is that the classes intended to be used this way only provide one ability and one ability only. It is an asset of any mixin class that it is not actually useful on its own. In fact, Sam had the right intuition here when he felt like these classes should be abstract. Making them abstract further solidifies their intent, prevents them from being used on their own, and thus prevents the class from becoming bloated with additional content as it evolves. The observant reader will have noticed that the relevant classes are indeed abstract in this version whereas they were not in the earlier post.

So when do we use mixins and when do we use composition? This is an excellent design question indeed and I am a bit uncomfortable providing any guidance at all due to the risk of blind observance to a rule of thumb. The fact is you should be aware of both approaches in your own world of software design. If you tend to fall into the trap of using inheritance for everything and find that you think about code sharing more than the abstraction that the inheritance provides then I would suggest strengthening your use of composition. If you find yourself constantly writing boiler plate code because you are strictly adhering to composition over inheritance for many small interfaces then you definitely want to consider whether mixins are appropriate. They are indeed powerful.

Note well that there is a distinct difference in the type of the resulting object when either of the two approaches are used. When composition is used you can decouple the type of the object from the implementation, whereas the use of mixins you receive the type and the implementation. Sometimes you want the type, like when your client code wants to accept any object that "HasRings" because the notion of Ringed-ness as a concept exists solely within the celestial body code. Sometimes you do not, such as when you want to ensure that celestial body code that operates on rounded celestial bodies rejects basketballs and oranges that also subscribe to Rounded behavior.

MATLAB itself has a few built-in mixin types, like matlab.mixin.Heterogenous, matlab.mixin.Copyable, and matlab.mixin.CustomDisplay. From these examples you can see some of these principles at work. Each of them have broad applicability yet a narrowness of scope. None of them really produce anything intrinsically valuable on their own, but provide a great deal of value when mixed into existing object structures. Have you ever used these mixin classes that are included with MATLAB? If not are you interested in working through some examples of their use? Do you write your own mixin classes in order to leverage the flexibility they provide?

Who ever thought that an ice cream shop would have such a lasting impact on the culture and ethos of software architecture? Actually who am I kidding? Ice cream is awesome, it was always destined for such greatness!


Get the MATLAB code

Published with MATLAB® R2015a

8 CommentsOldest to Newest

Sam Roberts replied on : 1 of 8
Hi Andy - thanks for the namecheck! So when is an Abstract class just an Abstract class, and when is it a mixin? Is there a technical distinction, or is it a distinction based on the purpose to which you want to put the class - perhaps mixins are more focused in functionality, or more intended to be reusable across projects? For example, in a current project (an application to automate various database and analysis tasks for a client) I have an abstract Task class, and subclasses SQLTask and MATLABTask. Task requires subclasses to implement a runTask method, but provides concrete properties such as taskName, taskDescription, and concrete methods to track statistics such as the number of times the task has been run, task timings and so on. I've been thinking of Task as just an abstract class - but perhaps Task should be thought of as a mixin? Should I have called it something like Runnable or Automatable? Perhaps I should have split it into two mixins, Runnable and Timeable? (By the way, I'm just noticing a tendency I have to name mixins with words ending in -able, like interfaces such as an IEnumerable in C# or Serializable in Java - is that wise?) To answer the questions in your last paragraph - I very regularly use Heterogeneous and CustomDisplay, but I haven't often needed Copyable. If you're thinking of future articles on those, I'd be most interested to see how you use Heterogeneous, as there are plenty of intricacies to get right with that. I also use a couple of my own mixins quite a bit. HandleHiddenMethods contains the same methods as handle, and just passes them straight through, but the methods are Hidden, so they don't clutter up help text. Informative has properties Name, Description, DetailedDescription, Notes and Tags (a cell array), and methods addTag, removeTag and hasTag, and allows subclasses to store that sort of meta-information. I'm also writing a card-game package in my spare time for fun, and I'm slowly implementing a Comparable mixin for that - it has an abstract compare method, that's required to accept two scalars and return -1, 0 or 1; and it then gives you scalar-expanded implementations of le, lt, ge, gt, eq, and ne, and min, max, median, sort and unique. I'm trying to extend it at the moment so that compare can also return NaN (which is proving more fiddly than it initially seemed).
Sean de Wolski replied on : 2 of 8
Sam, I like the idea of your HandleHiddenMethods mixin and wish I'd thought of it myself(!). Though, I might switch Handle and Hidden because Handle is also a verb, so I thought it was going to do something with hidden methods. I see classes that hide these very frequently. If possible, can you post it to the FEX?
Sam Roberts replied on : 3 of 8
Hi Sean, Good point about the naming - it made perfect sense to me at the time, but now that I have another point of view it does sound ambiguous. Yes, I think I could probably post it to the FEX - I'll take a look into it.
Eric S replied on : 4 of 8
There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton How about something like Handle_NoHiddenMethods
Andy Campbell replied on : 5 of 8
Hi Sam, Yes good question about what is and isn't a mixin. I think of it in terms of the purpose of the class. Is this a production class that has some purpose to fulfill in the rest of the software application? Not a mixin. For example, in the test framework we have a Constraint class with some abstract methods. This class has real meaning in the core of our qualification interfaces because testCase.verifyThat and its siblings fundamentally operate on constraints. It has an solid meaning as an object to refer to in the abstract. Something like: "Constraints take values (actual values in testing) and determine whether they are within the criteria for the constraint, optionally performing analysis as to why these values do or do not satisfy the constraint and communicating this information to the client." Then in our internal code we have something called an IgnoringCaseMixin. All this does is allow others classes to also ignore case as they see fit and it helps provide the interface such that the methods for ignoring case are common across all things that can ignore case. I would never need to create something that ignores case without it performing some other function. Your Task example sounds to me like a real interface that you are operating on with an abstraction that is useful on its own. Something consumes these Tasks and it also sounds like the Tasks do indeed provide task specific value adding methods. My first thought is that these are not mixins but rather one of the core interfaces your code base operates on. Do you find yourself wishing that other unrelated objects have Task behavior? If not I don't think its a mixin. It does sound to me like your HidesHandleMethods (my vote for the name) class is a mixin as well as the Comparable interface you are playing with. Mixins can certainly be used across projects but they don't need to be. You can use mixins within a project in order to share the ability across varying classes while minimizing coupling. Only the classes which need the mixin's small scoped functionality need inherit from it, no-one gets it as a side effect of some other base class they inherit from. I also don't think they neceessarily need to end in -able to be a mixin but they certainly can. In my mind, the decision to name something ending in -able is orthogonal to whether that thing is a mixin. Ultimately, what I think is more important is the concept of a mixin and the understanding that the use of mixins with multiple inheritance can be a powerful technique that can be quite safe as long as you ensure each mixin class is minimially small in scope and purpose. It allows us to use a lot of little building blocks to build our application, and we avoid building blocks that carry unrelated features with them along the way.
David Barry replied on : 6 of 8
Hi Andy, Thanks for another great post. We make use of the excellent matlab.mixin.CustomDisplay class for easily customizing display of our own internal classes. I see yet another class diagram and was just wondering if you managed to speak to your development colleagues about getting this functionality in to MATLAB as we spoke about in a previous blog post. Regards David
Andy Campbell replied on : 7 of 8
Hi David, I have indeed connected with some of my friends and this is something we are considering for possible inclusion in a future MATLAB version. -A
Greg Wolff replied on : 8 of 8
Hi David, There are a couple of File Exchange entries that use Doxygen to display MATLAB Class Hierarchies. Search the FEX for Doxygen and you'll see a few well rated results. Cheers, -Greg

Add A Comment

Your email address will not be published. Required fields are marked *

Preview: hide