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.
  • E Eytukan

    What is your way of dealing with a composition in a class? Will you force the user to pass the required values to the contained objects? Or you'll let the user set the contained object anytime later and check for it's validity everywhere? For example,

    class Rocket
    {
    Booster b1;
    Rocket(Boostertype bt, BoosterPower bp)
    {
    //check bp & bt values for acceptable range else throw an exception
    b1 = new Booster(bt,bp);
    }
    Launch()
    {
    b1.fire();
    //We are sure Booster is initialized
    }
    }

    Or it could be done this way

    class Rocket
    {
    Booster b1;
    Rocket()
    {

    }
    initBooster(Boostertype bt, BoosterPower bp)
    {

    b1 = new Booster(bt,bp);
    

    }
    Launch()
    {
    if(null!=b1)
    {
    if(b1.bp >100)
    {
    //Ok to launch
    }
    }
    // booster may not be initialized yet. so check and throw an exception if not inited.
    }
    }

    My preferred way is to enforce Rocket's constructor with params required for booster as well. Unless we pass a sensible value for the booster, rocket creation will fail. But my mate here seem to differ with my opinion. He doesn't want Rocket's creation to be disturbed by booster constructors parameters. Instead, when a Launch() is called , it should throw an exception saying Booster is not initialized/configured. Which one would you prefer?

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

    N Offline
    N Offline
    Nagy Vilmos
    wrote on last edited by
    #2

    It depends on how you want to interact with the composite member. I will often use an interface for the composite member that forces certain behavior on the parent. To continue with your example. Can a rocket exist without the booster? Yes, then it does not belong in the constructor; no, then it must be initialised. I would have:

    interface BoosterInterface {
    Booster getBooster();
    Boostertype getBoosterType();
    Boostertype getBoosterPower();
    void initBooster(Boostertype bt, BoosterPower bp);
    void setBooster(Booster bl);
    void setBoosterType(Boostertype bt);
    void setBoosterPower(BoosterPower bp);
    }

    class Rocket
    impliments BoosterInterface {
    // ya da ya
    }

    Having the interface means that you can of course force behaviour to the containing class. My two pennies worth.


    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

    E 1 Reply Last reply
    0
    • N Nagy Vilmos

      It depends on how you want to interact with the composite member. I will often use an interface for the composite member that forces certain behavior on the parent. To continue with your example. Can a rocket exist without the booster? Yes, then it does not belong in the constructor; no, then it must be initialised. I would have:

      interface BoosterInterface {
      Booster getBooster();
      Boostertype getBoosterType();
      Boostertype getBoosterPower();
      void initBooster(Boostertype bt, BoosterPower bp);
      void setBooster(Booster bl);
      void setBoosterType(Boostertype bt);
      void setBoosterPower(BoosterPower bp);
      }

      class Rocket
      impliments BoosterInterface {
      // ya da ya
      }

      Having the interface means that you can of course force behaviour to the containing class. My two pennies worth.


      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

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

      Makes sense. :thumbsup:

      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
      • E Eytukan

        What is your way of dealing with a composition in a class? Will you force the user to pass the required values to the contained objects? Or you'll let the user set the contained object anytime later and check for it's validity everywhere? For example,

        class Rocket
        {
        Booster b1;
        Rocket(Boostertype bt, BoosterPower bp)
        {
        //check bp & bt values for acceptable range else throw an exception
        b1 = new Booster(bt,bp);
        }
        Launch()
        {
        b1.fire();
        //We are sure Booster is initialized
        }
        }

        Or it could be done this way

        class Rocket
        {
        Booster b1;
        Rocket()
        {

        }
        initBooster(Boostertype bt, BoosterPower bp)
        {

        b1 = new Booster(bt,bp);
        

        }
        Launch()
        {
        if(null!=b1)
        {
        if(b1.bp >100)
        {
        //Ok to launch
        }
        }
        // booster may not be initialized yet. so check and throw an exception if not inited.
        }
        }

        My preferred way is to enforce Rocket's constructor with params required for booster as well. Unless we pass a sensible value for the booster, rocket creation will fail. But my mate here seem to differ with my opinion. He doesn't want Rocket's creation to be disturbed by booster constructors parameters. Instead, when a Launch() is called , it should throw an exception saying Booster is not initialized/configured. Which one would you prefer?

        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
        #4

        It's an interesting one to say the least. One of the principals of OO development is that you shouldn't return an object out of a constructor that requires further configuration to be useful*. In other words, you shouldn't need to set additional properties before the class is useful. In this particular case, the fact that you can get to the Launch code without setting it, and the first point that you notice that there's a failure is at this point would indicate that the Booster should have been applied earlier on. *Now, looking at your sample, it would seem that what you are looking at here is an object that would typically be composed using Dependency Injection, so it would be reasonable to assume that the DI code would actually compose your object for you. This would mean that you would be exposing a dependency that your code was reliant on - and this is where it gets slightly murkier. If you favour the wide constructor approach to composition, then every time you need to add an extra dependency to your class, you have to add it to your constructor, and add a backing field for that type. You may prefer the dependency property (I'm not using this in the WPF way here) approach, which means that you would expose a property for it - and this could be an auto property so you wouldn't need to add the field yourself as the compiler takes care of this for you behind the scenes.

        *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

        N 1 Reply Last reply
        0
        • E Eytukan

          What is your way of dealing with a composition in a class? Will you force the user to pass the required values to the contained objects? Or you'll let the user set the contained object anytime later and check for it's validity everywhere? For example,

          class Rocket
          {
          Booster b1;
          Rocket(Boostertype bt, BoosterPower bp)
          {
          //check bp & bt values for acceptable range else throw an exception
          b1 = new Booster(bt,bp);
          }
          Launch()
          {
          b1.fire();
          //We are sure Booster is initialized
          }
          }

          Or it could be done this way

          class Rocket
          {
          Booster b1;
          Rocket()
          {

          }
          initBooster(Boostertype bt, BoosterPower bp)
          {

          b1 = new Booster(bt,bp);
          

          }
          Launch()
          {
          if(null!=b1)
          {
          if(b1.bp >100)
          {
          //Ok to launch
          }
          }
          // booster may not be initialized yet. so check and throw an exception if not inited.
          }
          }

          My preferred way is to enforce Rocket's constructor with params required for booster as well. Unless we pass a sensible value for the booster, rocket creation will fail. But my mate here seem to differ with my opinion. He doesn't want Rocket's creation to be disturbed by booster constructors parameters. Instead, when a Launch() is called , it should throw an exception saying Booster is not initialized/configured. Which one would you prefer?

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

          B Offline
          B Offline
          BobJanova
          wrote on last edited by
          #5

          As Pete says, a constructor should always return a valid object, that is, you should be able to use it in normal situations. So the answer to the question depends on whether a Rocket can be useful without a Booster. In your simplistic example, where it has one method and that method throws an exception if it isn't set, it clearly can't, and therefore the Booster should be assigned in the constructor (and, if applicable, a null check applied there).

          1 Reply Last reply
          0
          • P Pete OHanlon

            It's an interesting one to say the least. One of the principals of OO development is that you shouldn't return an object out of a constructor that requires further configuration to be useful*. In other words, you shouldn't need to set additional properties before the class is useful. In this particular case, the fact that you can get to the Launch code without setting it, and the first point that you notice that there's a failure is at this point would indicate that the Booster should have been applied earlier on. *Now, looking at your sample, it would seem that what you are looking at here is an object that would typically be composed using Dependency Injection, so it would be reasonable to assume that the DI code would actually compose your object for you. This would mean that you would be exposing a dependency that your code was reliant on - and this is where it gets slightly murkier. If you favour the wide constructor approach to composition, then every time you need to add an extra dependency to your class, you have to add it to your constructor, and add a backing field for that type. You may prefer the dependency property (I'm not using this in the WPF way here) approach, which means that you would expose a property for it - and this could be an auto property so you wouldn't need to add the field yourself as the compiler takes care of this for you behind the scenes.

            *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

            N Offline
            N Offline
            Nagy Vilmos
            wrote on last edited by
            #6

            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 1 Reply Last reply
            0
            • E Eytukan

              What is your way of dealing with a composition in a class? Will you force the user to pass the required values to the contained objects? Or you'll let the user set the contained object anytime later and check for it's validity everywhere? For example,

              class Rocket
              {
              Booster b1;
              Rocket(Boostertype bt, BoosterPower bp)
              {
              //check bp & bt values for acceptable range else throw an exception
              b1 = new Booster(bt,bp);
              }
              Launch()
              {
              b1.fire();
              //We are sure Booster is initialized
              }
              }

              Or it could be done this way

              class Rocket
              {
              Booster b1;
              Rocket()
              {

              }
              initBooster(Boostertype bt, BoosterPower bp)
              {

              b1 = new Booster(bt,bp);
              

              }
              Launch()
              {
              if(null!=b1)
              {
              if(b1.bp >100)
              {
              //Ok to launch
              }
              }
              // booster may not be initialized yet. so check and throw an exception if not inited.
              }
              }

              My preferred way is to enforce Rocket's constructor with params required for booster as well. Unless we pass a sensible value for the booster, rocket creation will fail. But my mate here seem to differ with my opinion. He doesn't want Rocket's creation to be disturbed by booster constructors parameters. Instead, when a Launch() is called , it should throw an exception saying Booster is not initialized/configured. Which one would you prefer?

              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
              #7

              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 E 2 Replies Last reply
              0
              • 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