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. Refactoring Properties into Classes

Refactoring Properties into Classes

Scheduled Pinned Locked Moved Design and Architecture
csshelpquestionannouncement
7 Posts 5 Posters 5 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.
  • L Offline
    L Offline
    Leslie Sanford
    wrote on last edited by
    #1

    Say you have an interface:

    public interface IWidget
    {
    // Methods...

    // Properties...
    
    int Count
    {
        get;
        set;
    }
    

    }

    Let's pretend that a lot of classes will implement this interface. As a result, each class will have to implement the Count property. The implementation code in each class will be the same, more or less. So it's tempting to do this:

    public abstract Widget : IWidget
    {
    private int count = 0;

    public int Count
    {
        get
        {
            return count;
        }
        set
        {
            count = value;
        }
    }
    

    }

    Now instead of implementing the IWidget interface directly, classes derive from the abstract Widget base class. Let's say, however, that derived classes need to know when Count changes; they may need to do some house keeping. We could make Count virtual so that derived classes could do this:

    public class MyWidget : Widget
    {
    public override int Count
    {
    get
    {
    return base.Count;
    }
    set
    {
    base.Count = value;

            // Do stuff based on new count value...
        }
    }
    

    }

    I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property? But I'm not really interested in delving into this issue again, though feel free to comment. The next step is to factor out the Count property into its own class:

    public class Counter
    {
    private int count = 0;

    public event EventHandler CountChanged;
    
    // ...
    
    public int Count
    {
        get
        {
            return count;
        }
        set
        {
            if(count < 0)
            {
                throw new ArgumentOutOfRange("Count");
            }
    
            count = value;
    
            OnCountChanged(EventArgs.Empty);
        }
    }
    

    }

    Instead of Count being a property of the IWidget interface, it becomes an object that is passed to instances of IWidget derived classes. Derived classes hook up to the CountChanged event and do whatever house keeping is necessary when the event i

    L P O 3 Replies Last reply
    0
    • L Leslie Sanford

      Say you have an interface:

      public interface IWidget
      {
      // Methods...

      // Properties...
      
      int Count
      {
          get;
          set;
      }
      

      }

      Let's pretend that a lot of classes will implement this interface. As a result, each class will have to implement the Count property. The implementation code in each class will be the same, more or less. So it's tempting to do this:

      public abstract Widget : IWidget
      {
      private int count = 0;

      public int Count
      {
          get
          {
              return count;
          }
          set
          {
              count = value;
          }
      }
      

      }

      Now instead of implementing the IWidget interface directly, classes derive from the abstract Widget base class. Let's say, however, that derived classes need to know when Count changes; they may need to do some house keeping. We could make Count virtual so that derived classes could do this:

      public class MyWidget : Widget
      {
      public override int Count
      {
      get
      {
      return base.Count;
      }
      set
      {
      base.Count = value;

              // Do stuff based on new count value...
          }
      }
      

      }

      I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property? But I'm not really interested in delving into this issue again, though feel free to comment. The next step is to factor out the Count property into its own class:

      public class Counter
      {
      private int count = 0;

      public event EventHandler CountChanged;
      
      // ...
      
      public int Count
      {
          get
          {
              return count;
          }
          set
          {
              if(count < 0)
              {
                  throw new ArgumentOutOfRange("Count");
              }
      
              count = value;
      
              OnCountChanged(EventArgs.Empty);
          }
      }
      

      }

      Instead of Count being a property of the IWidget interface, it becomes an object that is passed to instances of IWidget derived classes. Derived classes hook up to the CountChanged event and do whatever house keeping is necessary when the event i

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi Leslie, I did not completely follow the story here. Count first was a property, I am not sure what it is intended for. If it counts the number of IWidgets, I guess you would like to have a private static count variable, and a public static property; but then interfaces don't allow for static things. And you would not need a setter, the constructor should be the only one modifying it. Now if you attempt to solve the static issue by making an explicit Counter class and object, that's fine except it de-encapsulates things: you are now responsible for passing the right counter to each of the Widget constructors. You could solve that by adding another class I think. But maybe I misunderstood you and you want something completely different... :)

      Luc Pattyn [Forum Guidelines] [My Articles]


      this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


      L 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi Leslie, I did not completely follow the story here. Count first was a property, I am not sure what it is intended for. If it counts the number of IWidgets, I guess you would like to have a private static count variable, and a public static property; but then interfaces don't allow for static things. And you would not need a setter, the constructor should be the only one modifying it. Now if you attempt to solve the static issue by making an explicit Counter class and object, that's fine except it de-encapsulates things: you are now responsible for passing the right counter to each of the Widget constructors. You could solve that by adding another class I think. But maybe I misunderstood you and you want something completely different... :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


        L Offline
        L Offline
        Leslie Sanford
        wrote on last edited by
        #3

        Luc Pattyn wrote:

        I did not completely follow the story here. Count first was a property, I am not sure what it is intended for.

        Erm, count was a bad example, I guess. It's not intended to mean anything other than demonstrating the example. It could have easily been called foo or whatever. I ran into this situation with my synth toolkit. I had a collection of synth components that shared the same sample rate. At first, I made sample rate a property in an interface that's implemented by synth component classes. I noticed a lot of code duplication, so I factored sample rate into a property in an abstract base class. Some derived classes need to know when the sample rate changes, so I made it a virtual property. Derived classes then have the option to override the property so that when it's set to a new value, they can react. This lead to the ambiguity I described in my post about when/where/if to call base class members. Finally, I factored sample rate out into a class of its own. This allowed components to share the same sample rate object. It also allowed me to change the sample rate from a single point. Components sharing the same sample rate object would then be updated automatically. I was trying to describe all of this in my post by using a generic "Widget" class and "Count" property. I should have been more concrete.

        L 1 Reply Last reply
        0
        • L Leslie Sanford

          Luc Pattyn wrote:

          I did not completely follow the story here. Count first was a property, I am not sure what it is intended for.

          Erm, count was a bad example, I guess. It's not intended to mean anything other than demonstrating the example. It could have easily been called foo or whatever. I ran into this situation with my synth toolkit. I had a collection of synth components that shared the same sample rate. At first, I made sample rate a property in an interface that's implemented by synth component classes. I noticed a lot of code duplication, so I factored sample rate into a property in an abstract base class. Some derived classes need to know when the sample rate changes, so I made it a virtual property. Derived classes then have the option to override the property so that when it's set to a new value, they can react. This lead to the ambiguity I described in my post about when/where/if to call base class members. Finally, I factored sample rate out into a class of its own. This allowed components to share the same sample rate object. It also allowed me to change the sample rate from a single point. Components sharing the same sample rate object would then be updated automatically. I was trying to describe all of this in my post by using a generic "Widget" class and "Count" property. I should have been more concrete.

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          Hi Leslie, if you moved out the Counter/SampleRate stuff away from IWidget/ISynth and into a separate class, basically making it (almost) global, I see no objection. I first was under the impression you were somehow aggregating interfaces, i.e. defining an interface in an hierarchical way, with Counter somehow inside it. And that would open some new doors, if it were possible, but in the end I understood the Counter/SampleRate stuff is orthogonal to the IWidget/ISynth stuff, you just took it out completely. :)

          Luc Pattyn [Forum Guidelines] [My Articles]


          this weeks tips: - make Visual display line numbers: Tools/Options/TextEditor/... - show exceptions with ToString() to see all information - before you ask a question here, search CodeProject, then Google


          1 Reply Last reply
          0
          • L Leslie Sanford

            Say you have an interface:

            public interface IWidget
            {
            // Methods...

            // Properties...
            
            int Count
            {
                get;
                set;
            }
            

            }

            Let's pretend that a lot of classes will implement this interface. As a result, each class will have to implement the Count property. The implementation code in each class will be the same, more or less. So it's tempting to do this:

            public abstract Widget : IWidget
            {
            private int count = 0;

            public int Count
            {
                get
                {
                    return count;
                }
                set
                {
                    count = value;
                }
            }
            

            }

            Now instead of implementing the IWidget interface directly, classes derive from the abstract Widget base class. Let's say, however, that derived classes need to know when Count changes; they may need to do some house keeping. We could make Count virtual so that derived classes could do this:

            public class MyWidget : Widget
            {
            public override int Count
            {
            get
            {
            return base.Count;
            }
            set
            {
            base.Count = value;

                    // Do stuff based on new count value...
                }
            }
            

            }

            I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property? But I'm not really interested in delving into this issue again, though feel free to comment. The next step is to factor out the Count property into its own class:

            public class Counter
            {
            private int count = 0;

            public event EventHandler CountChanged;
            
            // ...
            
            public int Count
            {
                get
                {
                    return count;
                }
                set
                {
                    if(count < 0)
                    {
                        throw new ArgumentOutOfRange("Count");
                    }
            
                    count = value;
            
                    OnCountChanged(EventArgs.Empty);
                }
            }
            

            }

            Instead of Count being a property of the IWidget interface, it becomes an object that is passed to instances of IWidget derived classes. Derived classes hook up to the CountChanged event and do whatever house keeping is necessary when the event i

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

            What you have just described is known as composition, and it is perfectly valid. It is one of the most frequently overlooked areas of aggregation in OOP, and is seriously underused. To my mind, composition is as important as inheritance in OO.

            Deja View - the feeling that you've seen this post before.

            H 1 Reply Last reply
            0
            • L Leslie Sanford

              Say you have an interface:

              public interface IWidget
              {
              // Methods...

              // Properties...
              
              int Count
              {
                  get;
                  set;
              }
              

              }

              Let's pretend that a lot of classes will implement this interface. As a result, each class will have to implement the Count property. The implementation code in each class will be the same, more or less. So it's tempting to do this:

              public abstract Widget : IWidget
              {
              private int count = 0;

              public int Count
              {
                  get
                  {
                      return count;
                  }
                  set
                  {
                      count = value;
                  }
              }
              

              }

              Now instead of implementing the IWidget interface directly, classes derive from the abstract Widget base class. Let's say, however, that derived classes need to know when Count changes; they may need to do some house keeping. We could make Count virtual so that derived classes could do this:

              public class MyWidget : Widget
              {
              public override int Count
              {
              get
              {
              return base.Count;
              }
              set
              {
              base.Count = value;

                      // Do stuff based on new count value...
                  }
              }
              

              }

              I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property? But I'm not really interested in delving into this issue again, though feel free to comment. The next step is to factor out the Count property into its own class:

              public class Counter
              {
              private int count = 0;

              public event EventHandler CountChanged;
              
              // ...
              
              public int Count
              {
                  get
                  {
                      return count;
                  }
                  set
                  {
                      if(count < 0)
                      {
                          throw new ArgumentOutOfRange("Count");
                      }
              
                      count = value;
              
                      OnCountChanged(EventArgs.Empty);
                  }
              }
              

              }

              Instead of Count being a property of the IWidget interface, it becomes an object that is passed to instances of IWidget derived classes. Derived classes hook up to the CountChanged event and do whatever house keeping is necessary when the event i

              O Offline
              O Offline
              originSH
              wrote on last edited by
              #6

              Leslie Sanford wrote:

              I've posted about this in the past. I don't like this approach because it seems to introduces an ambiguity. When overriding a virtual method or property, when should you call the base class version? And should the call be at the beginning or at the end of the virtual method or property? But I'm not really interested in delving into this issue again, though feel free to comment.

              hehe I know it's not the main issue but since you invited comments ... it's not ambiguous it's flexable. You should know (either because you wrote it or because the documentation tells you) exactly what happens in the base. You then have a choice of wether you want that functionality to happen before your code, after your code or not at all.

              1 Reply Last reply
              0
              • P Pete OHanlon

                What you have just described is known as composition, and it is perfectly valid. It is one of the most frequently overlooked areas of aggregation in OOP, and is seriously underused. To my mind, composition is as important as inheritance in OO.

                Deja View - the feeling that you've seen this post before.

                H Offline
                H Offline
                Heavy Storm
                wrote on last edited by
                #7

                It looks like a composition, but I'm my opinion, he's implementing the Observer Design Pattern. I think in his project (as in many others), a property from an object is more than a property -- since it's shared among many members, it could be seen as an object itself. So, you create and object and delegate to punch when the state changes. I think many people tend to believe since "it's just an int" or "it's just a string" it's not a object.

                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