Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Design and Architecture
  4. Simple composition - Your thoughts?

Simple composition - Your thoughts?

Scheduled Pinned Locked Moved Design and Architecture
questiontutorialdiscussion
17 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Nagy Vilmos

    Using the analogy of the rocket, you can still perform a lot of actions - giro tests, etc - without a booster. The booster is an added item, not necessarily an intrinsic part. If the rocket must have a booster, then I agree it must be a part of the constructor to ensure its presence.


    Panic, Chaos, Destruction. My work here is done. Drink. Get drunk. Fall over - P O'H OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett

    P Offline
    P Offline
    Pete OHanlon
    wrote on last edited by
    #8

    Nagy Vilmos wrote:

    If the rocket must have a booster, then I agree it must be a part of the constructor to ensure its presence.

    And that's the rub. What constitues a valid instance of the class? In the admittedly contrived example given, the only operation that could be performed was a Launch, so the booster is an intrinsic part of this particular example. Now, if this class were one I was designing, I would take a slightly different approach if this was a full lifecycle of a rocket. This particular rocket implementation is tightly coupled to a single booster. What happens if I want a rocket with more than one booster? Or I want to use one that's based on the ACME Fusion Drive 3000 elastic band? To that end, I'd consider that a design like this might be better:

    public class Rocket
    {
    public Rocket()
    {
    }

    public void PreLaunchTests()
    {
    OnPreLaunchTests();
    }

    public void Launch()
    {
    }

    protected virtual void OnPreLaunchTests()
    {
    }

    protected virtual void OnLaunch()
    {
    }
    }

    public class SingleBoosterRocket : Rocket
    {
    public List<IBooster> Boosters { get; private set; }

    public SingleBoosterRocket()
    {
    Boosters = new List<IBooster>();
    }

    public void AddBooster(IBooster booster)
    {
    Boosters.Add(booster);
    }

    protected override void OnPreLaunchTests()
    {
    // Do some pre launch tests.
    }

    protected override void OnLaunch()
    {
    if (Boosters.Count == 0)
    throw new NotEnoughBoostersException();
    // Do some other work.
    }
    }

    public class DualBoosterRocket : SingleBoosterRocket
    {

    public DualBoosterRocket() : base()
    {
    }

    protected override void OnPreLaunchTests()
    {
    // Do some pre launch tests.
    }

    protected override void OnLaunch()
    {
    if (Boosters.Count < 2)
    throw new NotEnoughBoostersException();
    // Do some other work.
    }
    }

    Again, this is a completely fabricated design, but this has the advantage of being more flexible. Ultimately, the design should be based on the real requirements, which is why I have steered well clear of saying that one approach is better than another in all cases. BTW - in case you're wondering, the actual composition in this sample has been moved to the containing object, rather than the actual rocket implementation, as that piece of code would be the one that decided what the composition entailed. The rules for the rocket have been

    E 1 Reply Last reply
    0
    • M Marc Clifton

      Neither. Rocket should be able to call a factory method "Boosters.GetBooster()", or some other suitable mechanism to acquire what it needs, when it needs it. Marc

      My Blog
      The Relationship Oriented Programming IDE
      Melody's Amazon Herb Site

      P Offline
      P Offline
      Pete OHanlon
      wrote on last edited by
      #9

      Funnily enough, that was the gist of the answer that I've just added above.

      *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

      "Mind bleach! Send me mind bleach!" - Nagy Vilmos

      CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

      M 1 Reply Last reply
      0
      • P Pete OHanlon

        Funnily enough, that was the gist of the answer that I've just added above.

        *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

        "Mind bleach! Send me mind bleach!" - Nagy Vilmos

        CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

        M Offline
        M Offline
        Marc Clifton
        wrote on last edited by
        #10

        Pete O'Hanlon wrote:

        Funnily enough, that was the gist of the answer that I've just added above.

        I read it, but your response was too wordy for me to figure out what you were saying! But none-the-less, two great minds, a single thought between them, eh? Dependency Injection, hmmm... it's really weird to me how we have these (what I consider to be) massive frameworks to support DI when all it really needs is a simple instantiation engine. Anyways, I'm getting distracted by the lure of an unoccupied soapbox. ;) Marc

        My Blog
        The Relationship Oriented Programming IDE
        Melody's Amazon Herb Site

        P 1 Reply Last reply
        0
        • M Marc Clifton

          Pete O'Hanlon wrote:

          Funnily enough, that was the gist of the answer that I've just added above.

          I read it, but your response was too wordy for me to figure out what you were saying! But none-the-less, two great minds, a single thought between them, eh? Dependency Injection, hmmm... it's really weird to me how we have these (what I consider to be) massive frameworks to support DI when all it really needs is a simple instantiation engine. Anyways, I'm getting distracted by the lure of an unoccupied soapbox. ;) Marc

          My Blog
          The Relationship Oriented Programming IDE
          Melody's Amazon Herb Site

          P Offline
          P Offline
          Pete OHanlon
          wrote on last edited by
          #11

          We internally have a DI engine that is only 60 lines or so of code, and it's good enough for our purposes when all we need is basic DI.

          *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

          "Mind bleach! Send me mind bleach!" - Nagy Vilmos

          CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

          M 1 Reply Last reply
          0
          • P Pete OHanlon

            Nagy Vilmos wrote:

            If the rocket must have a booster, then I agree it must be a part of the constructor to ensure its presence.

            And that's the rub. What constitues a valid instance of the class? In the admittedly contrived example given, the only operation that could be performed was a Launch, so the booster is an intrinsic part of this particular example. Now, if this class were one I was designing, I would take a slightly different approach if this was a full lifecycle of a rocket. This particular rocket implementation is tightly coupled to a single booster. What happens if I want a rocket with more than one booster? Or I want to use one that's based on the ACME Fusion Drive 3000 elastic band? To that end, I'd consider that a design like this might be better:

            public class Rocket
            {
            public Rocket()
            {
            }

            public void PreLaunchTests()
            {
            OnPreLaunchTests();
            }

            public void Launch()
            {
            }

            protected virtual void OnPreLaunchTests()
            {
            }

            protected virtual void OnLaunch()
            {
            }
            }

            public class SingleBoosterRocket : Rocket
            {
            public List<IBooster> Boosters { get; private set; }

            public SingleBoosterRocket()
            {
            Boosters = new List<IBooster>();
            }

            public void AddBooster(IBooster booster)
            {
            Boosters.Add(booster);
            }

            protected override void OnPreLaunchTests()
            {
            // Do some pre launch tests.
            }

            protected override void OnLaunch()
            {
            if (Boosters.Count == 0)
            throw new NotEnoughBoostersException();
            // Do some other work.
            }
            }

            public class DualBoosterRocket : SingleBoosterRocket
            {

            public DualBoosterRocket() : base()
            {
            }

            protected override void OnPreLaunchTests()
            {
            // Do some pre launch tests.
            }

            protected override void OnLaunch()
            {
            if (Boosters.Count < 2)
            throw new NotEnoughBoostersException();
            // Do some other work.
            }
            }

            Again, this is a completely fabricated design, but this has the advantage of being more flexible. Ultimately, the design should be based on the real requirements, which is why I have steered well clear of saying that one approach is better than another in all cases. BTW - in case you're wondering, the actual composition in this sample has been moved to the containing object, rather than the actual rocket implementation, as that piece of code would be the one that decided what the composition entailed. The rules for the rocket have been

            E Offline
            E Offline
            Eytukan
            wrote on last edited by
            #12

            Thanks for the example Pete :)

            Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.

            P 1 Reply Last reply
            0
            • M Marc Clifton

              Neither. Rocket should be able to call a factory method "Boosters.GetBooster()", or some other suitable mechanism to acquire what it needs, when it needs it. Marc

              My Blog
              The Relationship Oriented Programming IDE
              Melody's Amazon Herb Site

              E Offline
              E Offline
              Eytukan
              wrote on last edited by
              #13

              I think we can think about two scenarios: 1. First, On the ground, we "build" the rocket with boosters and make a launch. 2. We don't build or assemble a rocket, but when a launch is called, it acquires a booster and executes a launch. The second one is loosely tied. The Boosters.GetBooster() can be applied for both the scenarios?

              Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.

              M 1 Reply Last reply
              0
              • E Eytukan

                Thanks for the example Pete :)

                Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.

                P Offline
                P Offline
                Pete OHanlon
                wrote on last edited by
                #14

                Not a problem.

                *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                1 Reply Last reply
                0
                • P Pete OHanlon

                  We internally have a DI engine that is only 60 lines or so of code, and it's good enough for our purposes when all we need is basic DI.

                  *pre-emptive celebratory nipple tassle jiggle* - Sean Ewington

                  "Mind bleach! Send me mind bleach!" - Nagy Vilmos

                  CodeStash - Online Snippet Management | My blog | MoXAML PowerToys | Mole 2010 - debugging made easier

                  M Offline
                  M Offline
                  Marc Clifton
                  wrote on last edited by
                  #15

                  Pete O'Hanlon wrote:

                  We internally have a DI engine that is only 60 lines or so of code

                  Sweet! Marc

                  My Blog
                  The Relationship Oriented Programming IDE
                  Melody's Amazon Herb Site

                  1 Reply Last reply
                  0
                  • E Eytukan

                    I think we can think about two scenarios: 1. First, On the ground, we "build" the rocket with boosters and make a launch. 2. We don't build or assemble a rocket, but when a launch is called, it acquires a booster and executes a launch. The second one is loosely tied. The Boosters.GetBooster() can be applied for both the scenarios?

                    Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.

                    M Offline
                    M Offline
                    Marc Clifton
                    wrote on last edited by
                    #16

                    VuNic wrote:

                    The Boosters.GetBooster() can be applied for both the scenarios?

                    I think so. In the first scenario, the constructor can call GetBooster to get a concrete instance, though I think it would be much more preferable for Rocket to have a Build() method. In the second scenario, and this may be over the top, consider that we know that a rocket, among other things, has some form of propulsion mechanism, otherwise it wouldn't be a rocket. Now, a rocket might have a main engine, boosters, stages, ion engines, so forth, a whole slew of combinations of things. So if rocket is to have a "has a" relationship to booster, the concept of booster needs to be abstracted to "propulsion systems", ideally a collection of this abstraction type. The GetBooster factory might return a collection specific to the rocket's requirements. You can define specific collections as a concrete type (there's most likely a limited, well defined set of configurations). Each type (the configuration of propulsion systems) probably has specific launch behaviors. Therefore, the type itself contains all the logic for how to proceed with a launch, going from main engine firing, booster firing, stages, and final orbit maneuverings with ion engines. So, why should the rocket itself know how to do this? The rocket is just a container for a particular configuration. Maybe the rocket performs some coordination with other systems, but the execution of the launch should be delegated to the configuration type. Which is where functional programming can be used, not only for "computing" the launch, but also for ensuring that configurations, using discriminated unions, are permitted. :) Marc

                    My Blog
                    The Relationship Oriented Programming IDE
                    Melody's Amazon Herb Site

                    E 1 Reply Last reply
                    0
                    • M Marc Clifton

                      VuNic wrote:

                      The Boosters.GetBooster() can be applied for both the scenarios?

                      I think so. In the first scenario, the constructor can call GetBooster to get a concrete instance, though I think it would be much more preferable for Rocket to have a Build() method. In the second scenario, and this may be over the top, consider that we know that a rocket, among other things, has some form of propulsion mechanism, otherwise it wouldn't be a rocket. Now, a rocket might have a main engine, boosters, stages, ion engines, so forth, a whole slew of combinations of things. So if rocket is to have a "has a" relationship to booster, the concept of booster needs to be abstracted to "propulsion systems", ideally a collection of this abstraction type. The GetBooster factory might return a collection specific to the rocket's requirements. You can define specific collections as a concrete type (there's most likely a limited, well defined set of configurations). Each type (the configuration of propulsion systems) probably has specific launch behaviors. Therefore, the type itself contains all the logic for how to proceed with a launch, going from main engine firing, booster firing, stages, and final orbit maneuverings with ion engines. So, why should the rocket itself know how to do this? The rocket is just a container for a particular configuration. Maybe the rocket performs some coordination with other systems, but the execution of the launch should be delegated to the configuration type. Which is where functional programming can be used, not only for "computing" the launch, but also for ensuring that configurations, using discriminated unions, are permitted. :) Marc

                      My Blog
                      The Relationship Oriented Programming IDE
                      Melody's Amazon Herb Site

                      E Offline
                      E Offline
                      Eytukan
                      wrote on last edited by
                      #17

                      Hmm as I understand, the design decision completely relies on the exact requirement. More thinking is required to realize what is the system about. The more we are precise with the actual system, the better and sensible design we could make. Thanks for the inputs Marc. All learning for me :)

                      Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups