Loading ...
Sorry, an error occurred while loading the content.

[extremeprogramming] When does refactoring become framework building

Expand Messages
  • Jonas Karlsson
    Hi, We re trying to introduce XP practices on a fairly small project (3-5 developers). I think Bob Martin wrote that he couldn t think of a case where using
    Message 1 of 10 , Jan 3, 2000
    • 0 Attachment
      Hi,
      We're trying to introduce XP practices on a fairly small
      project (3-5 developers). I think Bob Martin wrote that he couldn't
      think of a case where using XP on a project would add risk -- I think
      a case where significant risk is added is when the people trying to
      switch over to XP don't know what they're doing. To reduce this risk,
      I'll try and get some help from this list.

      I've just read Fowler's refactoring book, so I'll start there.

      Fowler states that refactoring should be done where "code smells" can
      be found. At first I thought he said that refactoring is done when
      needed to make implementation of a new task easier. Then he seemed to
      add that refactoring should be done all the time, whenever bad smells
      were encountered. I love designing general purpose, reusable
      frameworks, but my co-developers have forced me to compromise on many
      occasions, saying that it adds complexity that is not needed at this
      point in time. Can I now go and sneak in my general purpose
      framework under the guise of refactoring ("Oh, I'll just split an
      interface here, create an abstraction layer there, push some methods
      down, and others up.. Then in February, I'll start on my assigned
      tasks!")?

      I get the impression that despite "You aren't going to need it", in
      order to refactor effectively, some judgements about what is likely to
      change in the future must be made.

      _jonas
    • Michael C. Feathers
      ... From: Jonas Karlsson To: Sent: Monday, January 03, 2000 4:56 PM Subject: [extremeprogramming]
      Message 2 of 10 , Jan 3, 2000
      • 0 Attachment
        ----- Original Message -----
        From: Jonas Karlsson <karlsson@...>
        To: <extremeprogramming@egroups.com>
        Sent: Monday, January 03, 2000 4:56 PM
        Subject: [extremeprogramming] When does refactoring become framework
        building
        > Fowler states that refactoring should be done where "code smells" can
        > be found. At first I thought he said that refactoring is done when
        > needed to make implementation of a new task easier. Then he seemed to
        > add that refactoring should be done all the time, whenever bad smells
        > were encountered. I love designing general purpose, reusable
        > frameworks, but my co-developers have forced me to compromise on many
        > occasions, saying that it adds complexity that is not needed at this
        > point in time. Can I now go and sneak in my general purpose
        > framework under the guise of refactoring ("Oh, I'll just split an
        > interface here, create an abstraction layer there, push some methods
        > down, and others up.. Then in February, I'll start on my assigned
        > tasks!")?

        To me, the most important way of avoiding this is to make
        sure that all of your code is being used. If you are not using
        a particular hook function, for instance, it is not necessary.
        If you have an abstract class with only one subclass and
        it isn't there to break a dependency, ditto.

        There are a couple of things that will keep you away
        from framework building. First of all, if you write your
        test cases first, you'll probably find creating things you
        don't immediately need tedious. Secondly, if you
        are making estimates and sticking to them as part of
        a team, and the rest of them are churning out correct
        tested code like mad, I doubt they'll give you until
        February to join in. :-)

        There is a really bright side, however. If you get a
        kick out of building generality into code, you'll
        probably be amazed at how your code evolves
        into both specific and general things over time,
        without a lot of up front planning.

        > I get the impression that despite "You aren't going to need it", in
        > order to refactor effectively, some judgements about what is likely to
        > change in the future must be made.

        Following Kent's lead, I've tried some experiments, delaying
        those judgements and it has worked out well. Just paying
        attention to the clarity of your code and duplication works.
        When your code can't be made any more understandable
        and you do not have duplication, you are at a stable point.
        The potential for movement in any direction is maximized.

        Michael

        ---------------------------------------------------
        Michael Feathers mfeathers@...
        Object Mentor Inc. www.objectmentor.com
        Training/Mentoring/Development
        -----------------------------------------------------
        "You think you know when you can learn, are more sure when
        you can write, even more when you can teach, but certain when
        you can program. " - Alan Perlis
      • Ron Jeffries
        ... Also consider getting a coach to come and help out. A little goes a long way ... ... Yes, refactoring is incremental and should be done all the time. When
        Message 3 of 10 , Jan 3, 2000
        • 0 Attachment
          At 04:56 PM 1/3/2000 -0500, Jonas Karlsson wrote:
          >I think a case where significant risk is added is when the people trying to
          >switch over to XP don't know what they're doing. To reduce this risk,
          >I'll try and get some help from this list.

          Also consider getting a coach to come and help out. A little goes a long
          way ...

          >I've just read Fowler's refactoring book, so I'll start there.
          >
          >Fowler states that refactoring should be done where "code smells" can
          >be found.

          Yes, refactoring is incremental and should be done all the time. When going
          gets tough, no one will have time or inclination to clean things up. So
          keep your room clean all the time, just like Mom said.

          >I love designing general purpose, reusable frameworks, but my
          >co-developers have forced me to compromise on many occasions, saying that
          >it adds complexity that is not needed at this
          >point in time. Can I now go and sneak in my general purpose framework
          >under the guise of refactoring

          Not only no, but hell no. Extreme programmers remove code that isn't used.
          They don't put it in. See the rules for code in Beck's book, p 109. Run the
          tests; Communicate everything needed; No duplicate code; minimal number of
          classes and methods. Doesn't say anything about excess abstraction. Sorry.

          >I get the impression that despite "You aren't going to need it", in
          >order to refactor effectively, some judgements about what is likely to
          >change in the future must be made.

          No, none. Make the code perfect for today. Then stop.

          Regards,

          Ron Jeffries
          Extreme Programming Training and Consultation
          ronjeffries@...
          web pages: http://www.XProgramming.com, http://www.armaties.com
          pgp key: http://www.armaties.com/pgpkey.htm
        • jbrains762@hotmail.com
          Hello, everyone... I am new to this group, and as a result, may respond to some *very old* articles, only because I am still learning the essentials of XP. I
          Message 4 of 10 , Nov 28, 2000
          • 0 Attachment
            Hello, everyone...

            I am new to this group, and as a result, may respond to some *very
            old* articles, only because I am still learning the essentials of XP.
            I have a question regarding the issues of "interface/implementation"
            v. "code for now only".

            In my relatively short experience as a developer -- only about three
            years -- I have learned that one effective way to insulate yourself
            from change is first to build a component entirely comprised of
            abstract classes and interfaces (I use Java terminology here) *then*
            implement the concrete classes that provide the behavior. In essence,
            I am building a "framework" even though the goal is not to reuse the
            framework, but rather to delay specifying the concrete classes to a
            configuration file. The result is that if implementation X
            (implementing Z) needs to be replaced with implementation Y, then all
            I need to do is write Y, have Y implement Z, then change a
            configuration file setting so that the ZFactory creates Ys instead of
            Xs.

            Clearly, this is not the simplest thing that could possibly work;
            however, it means that as long as I'm just replacing an
            implementation and not changing the overall behavior of the system, I
            do not have to recompile any existing code. I find this theoretically
            pleasing, even if I don't have hard evidence that it saves me any
            time.

            The simplest thing that could possibly work results in my having to
            change client code everywhere, from using Xs to using Ys, because the
            client code never used the Z interface, but the X class directly. I
            have to change all my test cases, too, because my integration-level
            tests all think I'm using Xs when now I'm using Ys.

            So am I missing something? or is this one area where the XP tenets
            don't quite hold well? I would argue that having a component built
            entirely of abstract classes and interfaces is less simple, but more
            valuable. I think XP is a hell of an idea, so I must be missing
            something.

            What don't I get, then?

            J. B. Rainsberger.
          • Laurent Bossavit
            ... Could you look for evidence that it *costs* you time ? Do you think you might find any ? If it doesn t take any longer to implement things that way, then
            Message 5 of 10 , Nov 28, 2000
            • 0 Attachment
              > Clearly, this is not the simplest thing that could possibly work;
              > however, it means that as long as I'm just replacing an
              > implementation and not changing the overall behavior of the
              > system, I do not have to recompile any existing code. I find this
              > theoretically pleasing, even if I don't have hard evidence that it
              > saves me any time.

              Could you look for evidence that it *costs* you time ? Do you think
              you might find any ?

              If it doesn't take any longer to implement things that way, then you
              are fine anyway. If it takes about the same time, you might
              experiment with extracting the interfaces after coding the
              implementation and observe whether the change seems to benefit
              your projects in any other measurable manner.

              I'm just making this up, but there is a way doing things the way
              you describe could cost you more time than it saves. If you need to
              alter the interfaces as a result of changes in the implementation,
              you would have been better off not writing the interface. If you avoid
              altering the interface, however much you are tempted to, and
              instead make the implementation more complex, that might cost
              you time in debugging the implementation.

              One way I like to think of the YAGNI principle is with reference to
              the old saying that "No battle plan survives contact with the
              enemy". I suspect, based on my scant experience, that no
              interface survives contact with its implementation.


              ========================================
              Bless n'a pas de modele : son ambition
              est d'en devenir un.
              ========================================
              Laurent Bossavit - Software Architect
              >>> laurent.bossavit@... <<<
              >>> 06 68 15 11 44 <<<
              >> ICQ#39281367 <<
              Agence Bless http://www.agencebless.com/
              ========================================
            • Phil Lewis
              ... ... Could it not be said that by writing tests before writing code, we are actually specifying the interface at that time? I kind of think that
              Message 6 of 10 , Nov 28, 2000
              • 0 Attachment
                > From: Laurent Bossavit [mailto:laurent.bossavit@...]
                >
                > > Clearly, this is not the simplest thing that could possibly work;
                > > however, it means that as long as I'm just replacing an
                > > implementation and not changing the overall behavior of the
                > > system, I do not have to recompile any existing code. I find this
                > > theoretically pleasing, even if I don't have hard evidence that it
                > > saves me any time.

                <SNIP>
                > I suspect, based on my scant experience, that no
                > interface survives contact with its implementation.

                Could it not be said that by writing tests before writing code, we are
                actually specifying the interface at that time?

                I kind of think that something ever so slightly 'smells' (no offense JB)
                about the idea of defining interfaces seperate from implementation. Not as a
                principle in itself. I think as a general principle it is probably fairly
                sound - a great deal of the Java base classes are done this way - but
                within the context of XP.

                I would be tempted to get it working without automatically doing this, and
                assume YAGNI. Then if at some later stage it looks like its about to be
                useful (coz I'm about to do the example JB gave), I might be tempted to
                refactor this idea into the code - but only where and when it proves useful.

                Hey, I've never done any XP, so don't listen to me!

                Phil
              • John Brewer
                ... essence, ... all ... of ... Design by interface is good stuff. This finally dawned on me after I read Coad and Mayfield s book Java Design . One thing
                Message 7 of 10 , Nov 28, 2000
                • 0 Attachment
                  --- In extremeprogramming@egroups.com, jbrains762@h... wrote:
                  > In my relatively short experience as a developer -- only about three
                  > years -- I have learned that one effective way to insulate yourself
                  > from change is first to build a component entirely comprised of
                  > abstract classes and interfaces (I use Java terminology here) *then*
                  > implement the concrete classes that provide the behavior. In
                  essence,
                  > I am building a "framework" even though the goal is not to reuse the
                  > framework, but rather to delay specifying the concrete classes to a
                  > configuration file. The result is that if implementation X
                  > (implementing Z) needs to be replaced with implementation Y, then
                  all
                  > I need to do is write Y, have Y implement Z, then change a
                  > configuration file setting so that the ZFactory creates Ys instead
                  of
                  > Xs.

                  Design by interface is good stuff. This finally dawned on me after I
                  read Coad and Mayfield's book "Java Design". One thing Coad is quick
                  to point out is that you don't want to have interfaces everywhere,
                  just in a few key places. The question is, how do you find these key
                  points?

                  Since I've gotten into XP, I let the code tell me. I code a straight
                  class first, and if I find duplication, I apply Fowler's "Extract
                  Superclass" and "Extract Interface" refactorings. It helps a lot that
                  Java has the notion of "compatible change" to a class. That is, you
                  can do lots of things to a class, like adding methods and fields,
                  without recompiling dependent classes.

                  The cool thing about refactoring is that I trust myself to be able to
                  handle these situations as the come up, so I don't need to design
                  ahead the way I used to.

                  John Brewer
                  Jera Design
                • Glen Alleman
                  ... are ... This is a very common practice in the hardware development world. Build the test fixture before the final board level product is finished, because
                  Message 8 of 10 , Nov 28, 2000
                  • 0 Attachment
                    --- In extremeprogramming@egroups.com, "Phil Lewis" <phil.lewis@k...>
                    wrote:

                    > Could it not be said that by writing tests before writing code, we
                    are
                    > actually specifying the interface at that time?

                    This is a very common practice in the hardware development world.
                    Build the test fixture before the final board level product is
                    finished, because how are you going to know if it works unless you
                    can plug it into something and not have it catch on fire?

                    > I kind of think that something ever so slightly 'smells' (no
                    offense JB)
                    > about the idea of defining interfaces separate from implementation.
                    Not as a
                    > principle in itself. I think as a general principle it is probably
                    fairly
                    > sound - a great deal of the Java base classes are done this way -
                    but
                    > within the context of XP.

                    Better than that it is a Best Practice in most CORBA shops to isolate
                    the underlying components from the IDL (if you use IDL that is). Look
                    at Peter Coad's Java Design Second Edition for some nice "programming
                    with interfaces" guidelines as well as Peter Haggar's Practical Java.
                    This is the point where I part company with YAGNI in the practical
                    sense. In a large scale system, NOT looking ahead and doing things
                    like isolating with interfaces and planning the IIOP XML stream
                    connections will only cause the whole team to jump up and down on
                    your body, when you announce that a refactoring is needed and all
                    their method signatures are also going to have to change.

                    > I would be tempted to get it working without automatically doing
                    this, and
                    > assume YAGNI. Then if at some later stage it looks like its about
                    to be
                    > useful (coz I'm about to do the example JB gave), I might be
                    tempted to
                    > refactor this idea into the code - but only where and when it
                    proves useful.

                    This of course depends on the development environment and the "teams"
                    rules for building Java objects. In the CORBA world "managing the
                    interfaces" is everything. Since the scalability of the distributed
                    object systems usually depend on how many remote object invocations
                    are performed for each Function Point, defining these interfaces LONG
                    in advance allows the system architects (people like me) to look at
                    the system from a macro view and start making models of performance,
                    reliability, fault tolerance, and all those annoying non-functional
                    attributes of commercially robust products

                    > Hey, I've never done any XP, so don't listen to me!

                    Neither do a fairly large number of the other members of this group
                    (at least according to the poll results (but there may be lots of
                    hanging chad there, so don't certify the results just yet).
                  • Kevin Smith
                    ... Others have hinted at what I will try to state more explicitly. Initially, when you have just one class, the simplest thing is to write the class without
                    Message 9 of 10 , Nov 28, 2000
                    • 0 Attachment
                      > In my relatively short experience as a developer -- only about three
                      > years -- I have learned that one effective way to insulate yourself
                      > from change is first to build a component entirely comprised of
                      > abstract classes and interfaces (I use Java terminology here) *then*
                      > implement the concrete classes that provide the behavior. In essence,
                      > I am building a "framework" even though the goal is not to reuse the
                      > framework, but rather to delay specifying the concrete classes to a
                      > configuration file. The result is that if implementation X
                      > (implementing Z) needs to be replaced with implementation Y, then all
                      > I need to do is write Y, have Y implement Z, then change a
                      > configuration file setting so that the ZFactory creates Ys instead of
                      > Xs.
                      >
                      > Clearly, this is not the simplest thing that could possibly work;
                      > however, it means that as long as I'm just replacing an
                      > implementation and not changing the overall behavior of the system, I
                      > do not have to recompile any existing code. I find this theoretically
                      > pleasing, even if I don't have hard evidence that it saves me any
                      > time.
                      >
                      > The simplest thing that could possibly work results in my having to
                      > change client code everywhere, from using Xs to using Ys, because the
                      > client code never used the Z interface, but the X class directly. I
                      > have to change all my test cases, too, because my integration-level
                      > tests all think I'm using Xs when now I'm using Ys.

                      Others have hinted at what I will try to state more explicitly.

                      Initially, when you have just one class, the simplest thing
                      is to write the class without an interface.

                      As soon as you have a second class doing the same thing,
                      it's time to refactor because you're violating the OAOO
                      (once and only once) rule. That might mean creating an
                      interface, or it might mean taking some other solution to
                      the problem.

                      Having the same (or very similar) code in multiple places in
                      your project is a smell, and should be refactored.

                      If you grow your interfaces this way, you will only have the
                      ones that you need. And, by golly, each one will do exactly
                      what it must, and nothing more. You won't have wasted time
                      up front guessing about which interfaces will contain which
                      functionality.

                      Hope it helps...

                      Kevin
                    • jbrains762@hotmail.com
                      ... work; ... this ... it ... are ... As soon as I read this, I saw that it must be so. In a way, my practice was equivalent to writing the test first,
                      Message 10 of 10 , Nov 29, 2000
                      • 0 Attachment
                        --- In extremeprogramming@egroups.com, "Phil Lewis" <phil.lewis@k...>
                        wrote:
                        >
                        > > From: Laurent Bossavit [mailto:laurent.bossavit@a...]
                        > >
                        > > > Clearly, this is not the simplest thing that could possibly
                        work;
                        > > > however, it means that as long as I'm just replacing an
                        > > > implementation and not changing the overall behavior of the
                        > > > system, I do not have to recompile any existing code. I find
                        this
                        > > > theoretically pleasing, even if I don't have hard evidence that
                        it
                        > > > saves me any time.
                        >
                        > <SNIP>
                        > > I suspect, based on my scant experience, that no
                        > > interface survives contact with its implementation.
                        >
                        > Could it not be said that by writing tests before writing code, we
                        are
                        > actually specifying the interface at that time?

                        As soon as I read this, I saw that it must be so. In a way, my
                        practice was equivalent to writing the test first, although I was
                        writing the test on paper instead of as code.

                        > I kind of think that something ever so slightly 'smells' (no
                        offense JB)
                        > about the idea of defining interfaces seperate from implementation.
                        Not as a
                        > principle in itself. I think as a general principle it is probably
                        fairly
                        > sound - a great deal of the Java base classes are done this way -
                        but
                        > within the context of XP.

                        No offence taken.

                        Certainly, after mapping out all the interfaces and ensuring that
                        they integrate properly, one can refactor: look for interfaces that
                        only have one foreseeable implementation and change the interface
                        into a concrete class. This is equivalent to XP practices, I think.

                        > I would be tempted to get it working without automatically doing
                        this, and
                        > assume YAGNI. Then if at some later stage it looks like its about
                        to be
                        > useful (coz I'm about to do the example JB gave), I might be
                        tempted to
                        > refactor this idea into the code - but only where and when it
                        proves useful.

                        On the other hand, if you know that you need two different
                        implementations and that you need to swap 'em, build the interface
                        first. To me, it's a question of looking interface-down instead of
                        implementation-up. Coding the test cases first looks like
                        an "interface-down" approach to me.

                        JBR.
                      Your message has been successfully submitted and would be delivered to recipients shortly.