'분류 전체보기'에 해당되는 글 539건

  1. 2003.08.03 Replace Recursion with Iteration (by Ivan Mitrovic) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  2. 2003.08.03 Replace Record with Data Class
  3. 2003.08.03 Replace Parameter with Method
  4. 2003.08.03 Replace Parameter with Explicit Methods
  5. 2003.08.03 Replace Nested Conditional with Guard Clauses
  6. 2003.08.03 Replace Method with Method Object <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  7. 2003.08.02 Replace Magic Number with Symbolic Constant <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  8. 2003.08.02 Replace Iteration with Recursion (by Dave Whipp) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  9. 2003.08.02 Replace Inheritance with Delegation
  10. 2003.08.02 Replace Exception with Test
  11. 2003.08.02 Replace Error Code with Exception
  12. 2003.08.02 Replace Delegation with Inheritance
  13. 2003.08.02 Replace Data Value with Object
  14. 2003.08.02 Replace Constructor with Factory Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  15. 2003.08.02 Replace Conditional with Visitor (by Ivan Mitrovic) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  16. 2003.08.02 Replace Conditional with Polymorphism
  17. 2003.08.02 Replace Assignment with Initialization (by Mats Henricson) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  18. 2003.08.02 Replace Array with Object
  19. 2003.08.02 Rename Method
  20. 2003.08.02 Remove Setting Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  21. 2003.08.02 Remove Parameter
  22. 2003.08.02 Remove Middle Man
  23. 2003.08.02 Remove Double Negative (by Ashley Frieze and Martin Fowler) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  24. 2003.08.02 Remove Control Flag
  25. 2003.08.02 Remove Assignments to Parameters
  26. 2003.08.02 Refactor Architecture by Tiers (Link only)
  27. 2003.08.02 Reduce Scope of Variable (by Mats Henricson) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  28. 2003.08.02 Push Down Method
  29. 2003.08.02 Push Down Field
  30. 2003.08.02 Pull Up Method

Replace Recursion with Iteration


Refactoring contributed by Ivan Mitrovic
        
You have code that uses Recursion and is hard to understand.

Replace Recursion with Iteration.

                        
                                
public void countDown(int n) {
        if(n == 0) return;

        System.out.println(n + "...");
        waitASecond();
        countDown(n-1);
}
                                        

                
After Refactoring:
                                                
public void countDown(int n) {
        while(n > 0) {
                System.out.println(n + "...");
                waitASecond ();
                n -= 1;
        }
                                        

Motivation


                
The old recruiting practice says, "Never hire a developer who computes the factorial using Recursion". Recursion is often used without considering alternatives before using it. Though it is true that recursive solution is often more elegant and easier to spot than the iterative solution, one should take care not to abuse it. Complex Recursion that is hard to understand should probably be considered a "bad smell" in the code and a good candidate to be replaced with Iteration (usually in combination with some other Refactorings). Moreover, iterative solutions are usually more efficient than recursive solutions as they don't incur the overhead of the multiple method calls.
                
We use Recursion when we have to perform a complex task that can be broken into the several subtasks. Recursion is implemented as a method that calls itself to solve subtasks. During the recursive call the values of the local fields of the method are placed on the method stack until the subtask performed by a recursive call is completed. Thus, whenever recursive method is called, local fields are put on the method stack and used again after the recursive call is completed. The general approach to Refactoring could probably be to implement the alternative Stack that "simulates" the method stack where the local fields could be placed (the java.util.Stack class is a good candidate for this job).

Sometimes a recursive solution doesn't preserve any local fields during the recursive call, which makes Refactoring much easier. This is the case with, so called, tail recursions. Tail recursions are recursions where the recursive call is the last line in the method. Tail recursions are generally considered a bad practice and should be replaced with Iteration. This technique is well known to the people who work on compiler implementations. A good compiler usually perfomes this Refactoring on the fly (this is the earliest known example that machines adopted some XP practices :)
        

Mechanics


  • Determine the base case of the Recursion. Base case, when reached, causes Recursion to end. Every Recursion must have a defined base case. In addition, each recursive call must make a progress towards the base case (otherwise recursive calls would be performed infinitely). In our example the base case is n == 0.

  • Implement a loop that will iterate until the base case is reached.

  • Make a progress towards the base case. Send the new arguments to the top of the loop instead to the recursive method.

  •                 
    The mechanics of some complicated Refactorings other than tail recursion Refactorings (for example, those that would use "home made" Stack to store the local fields of the method) are waiting to be defined. In the meantime, if you find yourself dealing with the particularly nasty recursion, don't forget that
    Substitute Algorithm
    is a valid Refactoring and a secret weapon when it comes to situations like this.

        

Example


    Sputnik launching countdown is a simple example of tail recursion:

    public class CountDown {
            public void countDown(int n) {
                    if(n == 0) return;

                    System.out.println(n + "...");
                    waitASecond();
                    countDown(n-1);
            }

            public void waitASecond() {
                    try {
                            Thread.sleep(1000);
                    }
                    catch (InterruptedException ignore) {
                    }
            }

            public static void main(String[] args) {
                    CountDown c = new CountDown();
                    c.countDown(10);
            }
    }
                                    
                    
    After Refactoring:

                                                    
    public class CountDown {
            public void countDown(int n) {
                    while(n > 0) {
                            System.out.println(n + "...");
                            waitASecond ();
                            n -= 1;
                    }

            }

            public void waitASecond() {
                    try {
                            Thread.sleep(1000);
                    }
                    catch (InterruptedException ignore) {
                    }
            }

            public static void main(String[] args) {
                    CountDown c = new CountDown();
                    c.countDown(10);
            }
    }




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Record with Data Class


You need to interface with a record structure in a traditional programming environment.x

Make a dumb data object for the record.



For more information see page 217 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Parameter with Method


An object invokes a method, then passes the result as a parameter for a method. The receiver can also invoke this method.

Remove the parameter and let the receiver invoke the method.


                int basePrice = _quantity * _itemPrice;
                discountLevel = getDiscountLevel();
                double finalPrice = discountedPrice (basePrice, discountLevel);



                int basePrice = _quantity * _itemPrice;
                double finalPrice = discountedPrice (basePrice);


For more information see page 292 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Parameter with Explicit Methods


You have a method that runs different code depending on the values of an enumerated parameter.

Create a separate method for each value of the parameter.


        void setValue (String name, int value) {
                if (name.equals("height")) {
                        _height = value;
                        return;
                }
                if (name.equals("width")) {
                        _width = value;
                        return;
                }
                Assert.shouldNeverReachHere();
        }


        void setHeight(int arg) {
                _height = arg;
        }
        void setWidth (int arg) {
                _width = arg;
        }


For more information see page 285 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Nested Conditional with Guard Clauses


A method has conditional behavior that does not make clear what the normal path of execution is

Use Guard Clauses for all the special cases


double getPayAmount() {
        double result;
        if (_isDead) result = deadAmount();
        else {
                if (_isSeparated) result = separatedAmount();
                else {
                        if (_isRetired) result = retiredAmount();
                        else result = normalPayAmount();
                };
        }
return result;
};        



double getPayAmount() {
        if (_isDead) return deadAmount();
        if (_isSeparated) return separatedAmount();
        if (_isRetired) return retiredAmount();
        return normalPayAmount();
};        


For more information see page 250 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Method with Method Object


You have a long method that uses local variables in such a way that you cannot apply
Extract Method


Turn the method into its own object so that all the local variables become fields on that object. You can then decompose the method into other methods on the same object.


class Order...
        double price() {
                double primaryBasePrice;
                double secondaryBasePrice;
                double tertiaryBasePrice;
                // long computation;
                ...
        }



        

Additional Comments


Using a Static Method



You can do this refactoring with a static method, but in this case you don't need the first field pointing back to the original object.

Alternative Steps with Temps


Marnix Klooster suggested an alternative to the mechanics. Rather than creating fields in the Method Object for all the temps, leave the temps as temps and only turn them into fields as you need to in order to use  Extract Method. It means you have to use a special form of Extract Method, but may help in reducing the scope of the temps. Of course you can use Reduce Scope of Variable afterwards on any temp that's only used in one method.

Contributors


  • Marnix Klooster


For more information see page 135 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Magic Number with Symbolic Constant


You have a literal number with a particular meaning.

Create a constant, name it after the meaning, and replace the number with it.



        double potentialEnergy(double mass, double height) {
                return mass * height * 9.81;
        }


        double potentialEnergy(double mass, double height) {
                return mass * GRAVITATIONAL_CONSTANT * height;
        }
        static final double GRAVITATIONAL_CONSTANT = 9.81;


For more information see page 204 of Refactoring

Additional Comments


Using a constant method



For this refactoring I used a symbolic constant, which is the most common Java idiom.

However an alternative is the constant method, which is a method of this form

public static double gravitationalConstant() {
        return 9.81;
}

This idiom is less familiar to C based programmers, but is very familiar to Smalltalkers (who didn't have constants in their language). On the whole I don't tend to use this in Java as it is less idiomatic to the language. However if you need to replace the simple return with a calculated value then it's worth changing the constant field to a constant method. (I guess there should be a refactoring for that....)

Contributors


  • Jutta Eckstein




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Iteration with Recursion


Refactoring contributed by Dave Whipp
  
You have a loop, and it is not obvious what each iteration is
doing

  
Replace Iteration with Recursion

  


unsigned greatest_common_divisor (unsigned a, unsigned b)
{
  while (a != b)
  {
    if (a > b)
    {
      a -= b;
    }
    else if (b > a)
    {
      b -= a;
    }
  }
}

  
  

  
  
unsigned greatest_common_divisor (unsigned a, unsigned b)
{
  if (a > b)
  {
    return greatest_common_divisor ( a-b, b );
  }
  else if (b > a)
  {
    return greatest_common_divisor ( a, b-a );
  }
  else // (a == b)
  {
    return a;
  }
}

  
  

Motivation


A problem with some loops is that it is difficult to work out what each iteration is doing. Formal methods folks use the term "loop-invariant" to describe the condition that exists as the result of each iteration. An invariant can be added to code as either comments or assertions. The use of good identifier names can often reduce the need for this type of comment. But in the example above, there are no appropriate identifiers to name -- and do you really want to introduce a temp?
  
The solution is to replace the iteration with recursion. Unlike most procedural looping constructs, a recursive function call can be given a meaningful name -- this name should reflect the loop invariant. (In the example, the loop invariant is that the gcd of a and b is unchanged on each iteration). This can often lead to mode understandable code, and can also open new opportunities for other refactorings.
  
Many people worry about performace when using recursion. As always, performace isn't an issue until you profile the code and find the hotspots. However, even with this caveat, it is useful to dispel the myth:
  
On many c/c++ compilers (most, if you enable optimisation), the recursive version will compile to code that is more efficient! This is because the compiler can perform the tail-recursion optimisation to eliminate the function call overhead, leaving just the body of the loop as the limiting factor. In the first version, the exit criteria is checked at the start of each iteration; in the latter, it is only reached at the end of the calculation. So the iterative version keeps checking if (a != b), while the recursive version never makes that check. (it is, of course, possible to re-write the while-loop to cure this, but that optimisation doesn't have the readability/simplicity advantages of the recursive version)

Mechanics


  • Identify the candidate loop. The loop should modify one or more scoped locals, and then return a result based on their final values.

  • Move the loop into a new function.

  • Compile and rerun tests.

  • Replace the loop with a function that accepts the local variables, and which returns the final result.

  • The implementation of the function should be an 'if' statement, which tests the looping condition (the condition expression in "while (condition) ...;"). The "then" clause should calculate/return the final result. The "else" clause should make the recursive call, with appropriately modified parameters.

  • Compile and rerun tests.

  • Now refactor the new function: You may be able to remove some temps, and find a better structure for the conditional in the recursive fuction

Example


    Start with this code.
    -
    -  

    unsigned foo (...)
    {
      ...

      unsigned a = f();
      unsigned b = g();

      ...

      while (a != b)
      {
        if (a > b)
        {
          a -= b;
        }
        else if (b > a)
        {
          b -= a;
        }
      }

      unsigned c = a;

      ...
    }

      
    This code has a pretty horrible loop: fortunately, we know what it does:  
      

    unsigned foo (...)
    {
      ...

      unsigned a = f();
      unsigned b = g();

      ...

      unsigned c = greatest_common_divisor(a, b);

      ...
    }

    unsigned greatest_common_divisor (unsigned a, unsigned b)
    {
      while (a != b)
      {
        if (a > b)
        {
          a -= b;
        }
        else if (b > a)
        {
          b -= a;
        }
      }
      return a;
    }

      
      
    I can now compile and test this.
      
    Now that I've extracted the loop (which may, itself, be a sufficient refactoring), I can change it to a recursive form:
    -
    -  


    unsigned greatest_common_divisor (unsigned a, unsigned b)
    {
      if (a != b)
      {
        if (a > b)
        {
          a -= b;
        }
        else if (b > a)
        {
          b -= a;
        }
        return greatest_common_divisor(a, b);
      }
      else
      {
        return a;
      }
    }

      
      
    This form isn't much better yet. There are 2 further simplifications: we fir
    st avoid modifying the parameters,
    -
    -


    unsigned greatest_common_divisor (const unsigned a, const unsigned b)
    {
      if (a != b)
      {
        if (a > b)
        {
          return greatest_common_divisor(a-b, b);
        }
        else if (b > a)
        {
          return greatest_common_divisor(a, b-a);
        }
       }
      else
      {
        return a;
      }
    }
      
      
    and, finally, we simplify the conditionals:  
      

    unsigned greatest_common_divisor (const unsigned a, const unsigned b)
    {
      if (a > b)
      {
        return greatest_common_divisor(a-b, b);
      }
      else if (b > a)
      {
        return greatest_common_divisor(a, b-a);
      }
      else // a == b
      {
        return a;
      }
    }




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Inheritance with Delegation


A subclass uses only part of a superclasses interface or does not want to inherit data.

Create a field for the superclass, adjust methods to delegate to the superclass, and remove the subclassing.




For more information see page 352 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Exception with Test


You are throwing an exception on a condition the caller could have checked first.

Change the caller to make the test first.


        double getValueForPeriod (int periodNumber) {
                try {
                        return _values[periodNumber];
                } catch (ArrayIndexOutOfBoundsException e) {
                        return 0;
                }
        }


        double getValueForPeriod (int periodNumber) {
                if (periodNumber >= _values.length) return 0;
                return _values[periodNumber];
        }


For more information see page 315 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Error Code with Exception



A method returns a special code to indicate an error.

Throw an exception instead.


        int withdraw(int amount) {
                if (amount > _balance)
                        return -1;
                else {
                        _balance -= amount;
                        return 0;
                }
        }



        void withdraw(int amount) throws BalanceException {
                if (amount > _balance) throw new BalanceException();
                _balance -= amount;
        }


For more information see page 310 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Delegation with Inheritance


You're using delegation and are often writing many simple delegations for the entire interface.

Make the delegating class a subclass of the delegate.




For more information see page 355 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Data Value with Object


You have a data item that needs additional data or behavior.

Turn the data item into an object.



For more information see page 175 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Constructor with Factory Method


You want to do more than simple construction when you create an object.

Replace the constructor with a factory method.


        Employee (int type) {
                _type = type;
        }


        static Employee create(int type) {
                return new Employee(type);
        }

For more information see page 304 of Refactoring

Additional Comments


Dimitri Paltchoun pointed out that as well as using Class.forName() and a string for a client to specify the created class, you can also use the class object itself. This would lead you to method like

  static Employee create(Class c){
    try{
      return (Employee)c.newInstance();
    }catch(Exception e){
      throw new IllegalException("Unable to instantiate" +c);
   }
  }

This would be called from this code

   Employee.create(Engineer.class);




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Conditional with Visitor


Refactoring contributed by Ivan Mitrovic


You have an "aggressive" Conditional that chooses different behaviour depending on the type of an object and repeats itself in a large number throughout the code.


Create concrete instance of Visitable object for each data type in Conditional. Create concrete instance of Visitor that encapsulates logic of each Conditional. Visit Visitable by Visitor.


More Information





***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Conditional with Polymorphism


You have a conditional that chooses different behavior depending on the type of an object.

Move each leg of the conditional to an overriding method in a subclass. Make the original method abstract.



        double getSpeed() {
                switch (_type) {
                        case EUROPEAN:
                                return getBaseSpeed();
                        case AFRICAN:
                                return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
                        case NORWEIGIAN_BLUE:
                                return (_isNailed) ? 0 : getBaseSpeed(_voltage);
                }
                throw new RuntimeException ("Should be unreachable");
        }




For more information see page 255 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Assignment with Initialization


Refactoring contributed by Mats Henricson

You have code that first declares a variable and then assigns a value to it

Make it into a direct initialization instead


void foo() {
   int i;
   // ....
   i = 7;
}



void foo() {
   // ...
   int i = 7;
}

Motivation


You often see functions in which the programmer has first declared lots of variables that will be used in that function, and then, further down the function, assigns values to them. This is often an artifact from older programming languages, where you had to declare in the beginning of the function all variables that are used in it. In C++ and Java this is not necessary, and in C++ this old style of programming can give you slower programs, since a declaration of a variable in C++ often means a call to the default constructor. In Java, declarations of variables are cheap, if not even free, but the problem is that you end up with unnecessary lines of code that adds no value to your program - you have two lines of code that can be expressed with one line of code.

Another problem is the risk that at some parts of the program a variable is not explicitly initialized, so that its initial value may not be obvious, or even undefined, as is often the case in C++.

Mechanics


  • Move the declaration of the variable to where that variable is first used,
    just before the assignment, making sure that you haven't reduced the scope
    of the variable so that it isn't in scope at some other place where it
    is used

  • Compile and test  

  • Replace the declaration and assignment with a direct initialization

  • Compile and test  

  • If appropriate, declare the temp as final, and compile and test again.


Example


    Start with this code.

    void foo() {
            int i;
            // ....
            i = 7;
    }

    The first move is to move the declaration of the variable to just before
    where it is assigned to:


    void foo() {
            // ....
            int i;
            i = 7;
    }

    I can now compile and test this. The most common mistake is that you have reduced the scope of the variable so that it no longer is in scope at some other place where it is used. Fortunately C++ and Java compilers will give you and error if this has happened.

    Then it is time to replace the declaration + assignment with the initialization:

    void foo() {
            // ....
            int i = 7;
    }

    If this also compiles and runs as before, then it is the end of the refactoring.

    However if the value of i doesn't change, then it's a good idea to make that explicit by declaring i as final



    void foo() {
            // ....
            final int i = 7;
    }




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Replace Array with Object


You have an array in which certain elements mean different things.

Replace the array with an object that has a field for each element.


        String[] row = new String[3];
        row [0] = "Liverpool";
        row [1] = "15";



        Performance row = new Performance();
        row.setName("Liverpool");
        row.setWins("15");


For more information see page 186 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Rename Method


The name of a method does not reveal its purpose.

Change the name of the method.


        

For more information see page 273 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Setting Method


A field should be set at creation time and never altered.

Remove any setting method for that field.



For more information see page 300 of Refactoring

Corrections


Using Final


Paul Haahr kindly pointed out to me that I've not been accurate with the use of final in this refactoring. The point that I missed is that you can't use a final field if the initialization is done in a separate method to the constructor. This the example at the bottom of page 301 (that uses initialize(id)) just does not compile. (My apologies for not testing that fragment, some do slip through the net....) If you want to use a separate method, you can't make the field final

This also means that the mechanics is incorrect. Making the field final should be the last step not the first, and can only be done if it's possible.

Contributors


  • Paul Haahr




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Parameter


A parameter is no longer used by the method body.

Remove it.




For more information see page 277 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Middle Man


A class is doing too much simple delegation.

Get the client to call the delegate directly.




For more information see page 160 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Double Negative


Refactoring contributed by Ashley Frieze and Martin Fowler

You have a double negative conditional.

Make it a single positive conditional


if ( !item.isNotFound() )


if ( item.isFound() )

Motivation


Double negatives are often frowned on by mavens of natural language. Often this frowning is inappropriate - certainly in English the double negative has its uses.

But that is not true in programming. There double negatives are just plain confusing. So kill them on sight.

Mechanics


  • If you don't have a method with the opposite sense, create one. The body can just call the original (you can fix that later).

  • Compile

  • Replace each double negative with a call to the new function

  • Compile and test after each replace

  • If the negative form of the method isn't used elsewhere, use Inline Method to inline it into the positive form

  • If you do need both forms, consider moving the body of the negative form over to the positive and reversing its sense, and then have the negative method call the positive one.

  • Consider using Substitute Algorithm if the positive form is difficult to understand.






***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Control Flag


You have a variable that is acting as a control flag for a series of boolean expressions.

Use a break or return instead.


For more information see page 245 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Remove Assignments to Parameters


The code assigns to a parameter.

Use a temporary variable instead.


        int discount (int inputVal, int quantity, int yearToDate) {
                if (inputVal > 50) inputVal -= 2;


        int discount (int inputVal, int quantity, int yearToDate) {
                int result = inputVal;
                if (inputVal > 50) result -= 2;


For more information see page 131 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Refactor Architecture by Tiers


Increasing architectural sophistication requires changing the localization of data access logic and processing logic

Move Data Access code logically and/or physically closer to the actual data source. Move processing logic out of the client and presentation tiers into the business tier.


For further information see page 116 of Core J2EE Patterns by Alur, Crupi, and Malks




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Reduce Scope of Variable


Refactoring contributed by Mats Henricson

You have a local variable declared in a scope that is larger than where it is used

Reduce the scope of the variable so that it is only visible in the scope where it is used

void foo()
{
    int i = 7;

    // i is not used here

    if (someCondition)
    {
        // i is used only within this block
    }

    // i is not used here
}



void foo()
{
    // i can not be used here

    if (someCondition)
    {
        int i = 7;

        // i is used only within this block
    }

    // i can not be used here
}



Motivation


There are several problems with local variables declared in too large scopes. One is that the variable may be declared but never used, as is the case if someCondition in the above example is false. Since declarations of variables in many cases costs computational cycles, you may end up wasting time for nothing. Another problems is that it clutters the name space. If you have several objects of the same type within the same scope, naming them can be quite contrieved - (user1, user2, user3 or firstUser, otherUser, nextUser). You may also end up having one variable hiding another variable with the same name in a larger scope, something most seasoned programmers can testify is very confusing and error prone.


Mechanics


  • Move the declaration of the variable to the scope where that variable is used, making sure that you haven't reduced the scope of the variable too much, so that it isn't in scope at some other place where it is used

  • Compile and test  

Additional Comments


When I'm writing new code I find I don't scope my temps any less than method scope. This is because I keep my methods short, so reducing scope any further doesn't add much value. The value of this refactoring is in breaking up a large method. Doing this refactoring can help you see where a variable is used. As such it's a good move before doing Extract Method.

Also, don't forget you can do this on a field that's only used by one method.

--Martin Fowler




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Push Down Method


Behavior on a superclass is relevant only for some of its subclasses.

Move it to those subclasses.


For more information see page 328 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Push Down Field


A field is used only by some subclasses.

Move the field to those subclasses.



For more information see page 329 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

Pull Up Method



You have methods with identical results on subclasses.

Move them to the superclass.

        

For more information see page 322 of Refactoring




***** 아름다운프로님에 의해서 게시물 복사 + 카테고리변경되었습니다 (2003-12-18 17:27)
Posted by 아름프로

BLOG main image

카테고리

분류 전체보기 (539)
이야기방 (19)
토론/정보/사설 (16)
IBM Rational (9)
U-IT (0)
SOA/WS/ebXML (110)
개발방법론/모델링 (122)
J2SE (34)
J2EE (60)
DataBase (39)
Open Projects (30)
BP/표준화 (50)
Apache Projects (15)
Web/보안/OS (22)
Tools (7)
AJAX/WEB2.0 (1)
Linux/Unix (1)
영어 (0)
비공개방 (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28

글 보관함

Total :
Today : Yesterday :