Software to slice bread

In the dark ages of programming, functions acted on data. To slice your bread, you passed a bread data structure to a slice function:

    slice(bread);

Then came object oriented programming. Instead of having an external function slice our bread, we would ask the bread to slice itself by calling the slice method on a bread object:

    bread.slice();

Obviously a vast improvement.

Now object oriented programming has become more refined. First we create a bread-slicing object and then we simply pass bread objects to the slice method on the bread-slicer:

    BreadSlicer slicer = new BreadSlicer();
    slicer.slice(bread);

More food analogies to software development

35 thoughts on “Software to slice bread

  1. BreadSlicer also implements the interface Slicer because you might be slicing other objects.

  2. It’s worth remembering that the return value from BreadSlicer is a BreadSliceIterator, which is a subclass of CarbIterator (extended with a fallDown() that ensures it falls a certain direction if mCarbState & CARB_STATE_BUTTERED).

  3. For truly modern software design, you should have a BreadSlicerFactory to create the BreadSlicer, and a BreadSlicerFactoryManager to manage the BreadSlicerFactory.

  4. Maybe I’m lazy, but I just use std::sandwich. It’s easier & the default has crusts cut off.

  5. Giorgio: I agree. I’m suspicious of any class whose name end in -er. Sometime it’s justified, but usually not. It’s a sign of a worst-of-both-worlds approach, more complicated than a purely functional design or a simple OO design.

  6. Bread does not slice itself in the real-world. If what is being built is a simulation, I would agree that bread.slice() is a good model. Otherwise, I would argue for a more complex service than a bread slicer (for example, an authentication service), modeling as a service would be both a more ‘accurate’ model and more flexible in code. But a service is essentially a function, so we’re back to square one.

  7. Question: If no one likes object oriented programming, why do all my profs talk about it as the be all and end all of programing techniques? And if you don’t like them, why do you use them?

  8. It really depends upon how many types or sizes of bread need slicing. A factory will always be overkill if all we ever wanted was to make a buttered slice with some crisps on top. I do like to keep room aside for a factory, and only go all out when someone requires a feature like thin slices or sausages sliced. Heavy OO too early often leaves you with unwanted dependencies, something OO was designed to reduce. The “er” suffix also bothered me, mixing verbs and nouns, tense, or using plural qualifiers always makes code smell.

  9. Canageek: I don’t think many people dislike OOP per se, only how OOP is often done in practice. At least that’s how I feel. What I dislike is cargo cult OOP, programmers who get a whiff of OOP and imitate it without understanding.

    In the abstract, there’s hardly any difference between foo(bar) and bar.foo(), and yet some people insist that the latter is better, though they can’t say why. In some contexts, bar.foo() may indeed be better, but you can’t say in isolation. Good OOP isn’t so much about how code looks line-by-line but rather about how the pieces fit together. Turning a function into a class method could be a good idea if enables you to reduce the size of your code by using polymorphism. But just saying “methods are better than functions” in general is silly.

    Software frameworks are responsible for some of the excesses I parody in my bread slicer example. (By the way, I suspect some readers will not see that the last example is meant as a joke because they are so used to similar code.) These frameworks try to be all things to all people, and so they come up with monstrosities like BreadSlicer classes.

    For example, I remember when I wrote Java briefly a dozen years ago I had to instantiate a calendar object before I could compare two dates. I needed to create a Gregorian calendar object despite the fact that (1) it was the only calendar that Java supported at the time, and (2) it’s the calendar used by the vast majority of humanity, at least in business. But just in case someone someday may want to use an obscure calendar, let’s make everyone create a calendar object.

  10. As abused as it often is, OOP generally has better discoverability than undecorated function names.

  11. …I remember when I wrote Java briefly a dozen years ago I had to instantiate a calendar object before I could compare two dates…
    It’s possible you picked the worst case of Java API ever.

  12. Ah yes, the classic example I give from the Java API is:

    Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File("MyData.xml"));

    This could be:

    XML xml = parseXMLFile("MyData.xml");

    and then people could actually tell what’s going on instantly instead of having to decipher which 90% of the line they should ignore. As John points out, it’s not about the single-line comparisons; it’s more about the hours of searching that it took to figure out that one line, all the while not knowing whether it was actually possible to use any of these classes, or if they were just a series of increasingly outrageous jokes inserted by some jaded developer at what was then Sun.

    Additionally, think about the huge number of useless temporary objects created if you need to perform that action many times. It appears to create a new DocumentBuilderFactory and DocumentBuilder every single time it’s used, all for something that needs no objects whatsoever. It’s hard to imagine the mindset of the people who designed almost the entire API in this style (or more likely a committee of people, since as the saying goes, “none of us is as dumb as all of us”). *sigh*

  13. Ah. In my very brief (read: almost zero) experience with them I liked the fact I could count on certain variables being available to functions instead of relying on global variables or passing said variable to each and every function that needs it…and every function they will be called from.

    I was thinking of how I would make a character generator for D&D:
    In C++ I could make a character object that had hitpoints as a property. (Forgive me if I’m using terminology wrong; The professor who taught me OO programing was one of the worst I’ve ever encountered). Then I could make functions in that object to get how man hit points the character has, and change how many it has. Then when I need to level up the character, or take a feat that adds to the total, I can just call those classes.

    In C I could do the same thing, but I’d have to use a global variable, or pass around a giant array that contains all of the characters statistics, and remember which square held what.

    Actually, is there any difference between all my functions being children of the character object, and thus having access to its variables, and just using a global variable? I guess it would matter more if I were writing a game or such, and had more then one character.

  14. I actually think the BreadSlicer design is good. And in a way, as has been mentioned, it is a reductio ad absurdum of the attachment to “objects” and in favor of a functional design. Here are some real examples of why BreadSlicer is good:

    A typical OO framework embeds notions of equality and comparability and string representation into some default method that must be overridden. To get around that, one really has to go toward the “-er” design.

    So we have Sorter and Comparator in order to be able to sort collections according to non-default criteria. toString() in Java and the like is horrible, because often I want to output something in different formats.

    My conclusion, therefore, is not that BreadSlicer is bad. My conclusion is that various languages require going through hoops in order to express very simple and obvious designs.

  15. Preston L. Bannister

    First, you invented self-slicing bread. Personally, I find this a little disturbing … and prefer a bread knife.

    Second, been reading up on the Spring framework of late. Globs of XML to perform dynamic late-binding of Java objects. Your example is a model of brevity and clarity, in contrast. Very tedious … and yet another example of re-implementing Lisp, badly. As a framework with a history, they have to preserve every variant that someone once thought was clever. The end result is excessively complex. And a bit silly.

  16. No doubt the BreadSlicer class is inherited from the Slicer class, and it has siblings such as the EggSlicer, the PineappleSlicer and the BaloneySlicer. (Only 25 bucks if you call in the next five minutes…)

  17. How it should be done in 2012 (in Scala):

    val bread = new Bread extends Sliceable
    bread.slice

    That way the slice implementation is in a different class (technically a mixin or ‘trait’ in Scala), so that bread doesn’t need to know how to slice it’s self. Best of both worlds.

  18. I outsourced this project and for 5 rupees a day my bread arrives pre-sliced in a bag with a tie. Check at your local store if you don’t believe me. ;)

  19. How often would we really want to allow for multiple BreadSlicer objects? (OK,something like the bakery domain might be an example). So how wrong would it be to use a static class (or class method, or whatever, depending on the language)?

    If there’s only one way to do it, then we’d just have

    BreadSlicer.slice(bread)

    … which isn’t much different from the first, “dark days” example.

  20. Ugh! Just looked through some past projects and am seeing many classes ending with -er: User, Customer, SalesOrder, PurchaseOrder, Carrier, InventoryTransfer, Workcenter, …

  21. Gunther: The examples you gave are genuine nouns, not verbs made into nouns by adding -er. So I should refine my earlier remark to say I’m suspicious of class names that are gerunds (is that the right grammatical term?) made from nouns.

    Software objects are supposed to represent real-world objects, i.e. nouns. When you make a verb into a noun by adding -er, that’s evidence that maybe you really need a function and not an object.

  22. Olivier Demeijer


    Collection<> breadSlices = Bread.intoSlices(bread);

    bread should be gc asap, as it no longer exists as such : it was sliced (immutability !!), resulting in its transformation in a Collection of BreadSlice (what is returned by slice(bread) actually ?)
    Bread.intoSlices(), static method, which is more or less equivalent to slice(bread)

    Cutlery is over-engineering in my/the wonderfull world of OOP :)

  23. Bread implements Sliceable.
    Slicer interface, has a slice() method taking a Sliceable as argument.
    KitchenModule Binds Sclicer to Knife.

    Then you wouldn’t know about knife really, but can use it:

    Slicer s = Injector.getInstance(Slicer.class);
    s.slice(bread);

Comments are closed.