0

Sometimes I find it useful to have a single class with multiple instances (configured differently via their properties), rather than multiple classes (inheritance).

??? Pattern

  • Single class (Fruit)
  • Different fruit are instances of Fruit, with properties configured correctly.
  • Behavior implemented as blocks.

class Fruit {
    var name: String
    var color: UIColor
    var averageWeight: Double
    var eat: () -> ()
}

class FruitFactory {
    static func apple() -> Fruit {
        let fruit = Fruit()
        fruit.name = "Apple"
        fruit.color = UIColor.redColor()
        fruit.averageWeight = 50
        fruit.eat = {
            washFruit(fruit)
            takeBite(fruit)
        }
        return fruit
    }

    static func orange() -> Fruit {
        let fruit = Fruit()
        fruit.name = "Orange"
        fruit.color = UIColor.orangeColor()
        fruit.averageWeight = 70
        fruit.eat = {
            peelFruit(fruit)
            takeBite(fruit)
        }
        return fruit
    }
}

Inheritance Pattern

For reference, the same could have been implemented using inheritance:

  • Multiple classes (Fruit, Apple, Orange)
  • Different fruit are classes that inherit from Fruit.
  • Behavior implemented using standard methods that are overridden in subclasses.

class Fruit {
    var name: String
    var color: UIColor
    var averageWeight: Double
    func eat() {
        // abstract method
    }
}

class Apple: Fruit {
    var name = "Apple"
    var color = UIColor.redColor()
    var averageWeight = 50

    override func eat() {
        washFruit(self)
        takeBite(self)
    }
}

class Orange: Fruit {
    var name = "Orange"
    var color = UIColor.orangeColor()
    var averageWeight = 70

    override func eat() {
        peelFruit(self)
        takeBite(self)
    }
}

class FruitFactory {
    static func apple() -> Fruit {
        return Apple()
    }

    static func orange() -> Fruit {
        return Orange()
    }
}

What is the first pattern called?

Are there any resources to help me decide when to use one of these patterns over the other?


Off the top of my head, I can think of at least one reason to prefer inheritance:

  • Imagine we need to add a new property to Apple, but not to Orange (e.g. averageCoreWeight). If you use inheritance this is trivial. If you use the first pattern, you will be left with a property that is only sometimes used.
  • The first pattern looks like a variation on Abstract Factory, though with a decidedly functional bent. Something you might see in Javascript, which is probably the example language. It's obvious advantage is that it prefers composition over inheritance. Note that many of the GOF patterns are just workarounds for things that functional languages can do inherently. – Robert Harvey Oct 15 '15 at 0:27
  • I'm basing this loosely off of Swift. – Senseful Oct 15 '15 at 0:31
  • Possibly the Strategy pattern? github.com/ochococo/Design-Patterns-In-Swift#-strategy – Robert Harvey Oct 15 '15 at 0:38
  • The GOF said this "Favor composition over inheritance" your 2nd example is what I call vertical inheritance, a term I coined when studying what composition is. In Composition your factory could take in an Interface of type fruit. Allowing the resulting object to be composed into what is desired from the outside. I call this horizontal inheritance because the container had a fruit property. That container then although not technically a fruit has the property or containment of a fruit. – John Peters Oct 15 '15 at 6:04
  • 1
    Prototype inheritance – coredump Oct 15 '15 at 22:22
1

What is the first pattern called?

The first pattern looks to be the Strategy pattern disguised as the Factory pattern. I assume your goal is to have different objects conforming to the interface of a Fruit, possibly implementing different algorithms and values for members.

the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm's behavior to be selected at runtime.

Protocols in Swift (called Interfaces in many other languages) are often used for the strategy pattern, since classes implementing a protocol do not otherwise have to have anything in common. They don't have to derive from the same base class or have the same members (other than what the protocol defines).

Are there any resources to help me decide when to use one of these patterns over the other?

The main way to help you decide about applying a pattern is to first be aware of various patterns. There are numerous books and online resources where patterns are cataloged and explained. Searching for software design patterns is a good start.

After you learn an interesting pattern, experience and judgement come into play in deciding where to use it. It is a trap to try to apply a given pattern indiscriminately. Yet, the prospect of trying something new is a siren's call that often leads us into choosing a pattern before the problem presents itself. Do better than me and avoid that mistake.

1

When you have a base object that you then create modified copies of, you are using the Prototype pattern. The original object (the Fruit in this case) serves as a prototypical template from which you build your individual fruits. Because they all derive from the original Fruit class, they have a prototypical inheritance relationship (as originally noted by @coredump).

You don't specify what language you are using, but Javascript is built entirely using the prototypical model rather than the classical model for inheritance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.