'개발방법론/모델링/Refactoring'에 해당되는 글 96건

  1. 2003.08.02 Replace Delegation with Inheritance
  2. 2003.08.02 Replace Data Value with Object
  3. 2003.08.02 Replace Constructor with Factory Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  4. 2003.08.02 Replace Conditional with Visitor (by Ivan Mitrovic) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  5. 2003.08.02 Replace Conditional with Polymorphism
  6. 2003.08.02 Replace Assignment with Initialization (by Mats Henricson) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  7. 2003.08.02 Replace Array with Object
  8. 2003.08.02 Rename Method
  9. 2003.08.02 Remove Setting Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  10. 2003.08.02 Remove Parameter
  11. 2003.08.02 Remove Middle Man
  12. 2003.08.02 Remove Double Negative (by Ashley Frieze and Martin Fowler) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  13. 2003.08.02 Remove Control Flag
  14. 2003.08.02 Remove Assignments to Parameters
  15. 2003.08.02 Refactor Architecture by Tiers (Link only)
  16. 2003.08.02 Reduce Scope of Variable (by Mats Henricson) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  17. 2003.08.02 Push Down Method
  18. 2003.08.02 Push Down Field
  19. 2003.08.02 Pull Up Method
  20. 2003.08.02 Pull Up Field
  21. 2003.08.02 Pull Up Constructor Body
  22. 2003.08.02 Preserve Whole Object
  23. 2003.08.02 Parameterize Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  24. 2003.08.02 Move Method <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  25. 2003.08.02 Move Field
  26. 2003.08.02 Move Class (by Gerard M. Davison) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  27. 2003.08.02 Move Business Logic to Session (Link only)
  28. 2003.08.02 Merge Session Beans (Link only)
  29. 2003.08.02 Localize Disparate Logic (Link only)
  30. 2003.08.02 Introduce Synchronizer Token (Link only)-냉무-

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 아름프로

Pull Up Field


Two subclasses have the same field.

Move the field to the superclass.



For more information see page 320 of Refactoring




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

Pull Up Constructor Body


You have constructors on subclasses with mostly identical bodies.

Create a superclass constructor; call this from the subclass methods.


class Manager extends Employee...
        public Manager (String name, String id, int grade) {
                _name = name;
                _id = id;
                _grade = grade;
        }


        public Manager (String name, String id, int grade) {
                super (name, id);
                _grade = grade;
        }


For more information see page 325 of Refactoring




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

Preserve Whole Object


You are getting several values from an object and passing these values as parameters in a method call.

Send the whole object instead.


                int low = daysTempRange().getLow();
                int high = daysTempRange().getHigh();
                withinPlan = plan.withinRange(low, high);
                            


                withinPlan = plan.withinRange(daysTempRange());

For more information see page 288 of Refactoring




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

Parameterize Method


Several methods do similar things but with different values contained in the method body.

Create one method that uses a parameter for the different values.



Corrections


Clarifying the Mechanics


I've since (after a suggestion from Prof Kahlbrandt) found better mechanics for this refactoring (changes are in bold)

  • Create a parameterized method that can be substituted for each repetitive method

  • Compile

  • Replace the body of one method with a call to the new method

  • Compile and Test

  • Use Inline Method on the old method

  • Repeat for all the methods.


  • Contributors


    • Bernd Kahlbrandt

    For more information see page 283 of Refactoring




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

    Move Method


    A method is, or will be, using or used by more features of another class than the class on which it        is defined.

    Create a new method with a similar body in the class it uses most. Either turn the old method into a simple delegation, or remove it altogether.

      

    For more information see page 142 of Refactoring

    Additional Comments


    Marian Vittek sent an example  for moving a method to a method argument.

    class Project {
      Person[] participants;
    }

    class Person {
      int id;
      boolean participate(Project p) {
        for(int i=0; i           if (p.participants[i].id == id) return(true);
        }
        return(false);
      }  
    }

    ... if (x.participate(p)) ...


    After applying the move you end up with


    class Project {
      Person[] participants;
      boolean participate(Person x) {
        for(int i=0; i           if (participants[i].id == x.id) return(true);
        }
        return(false);
      }  
    }

    class Person {
      int id;
    }

    ... if (p.participate(x)) ...



    He also points out that the part of the Move Method mechanics that reads Determine how to reference the correct target object from the source, should be replaced by Determine how to reference the correct
    target object from the source or from arguments of the method
    which is more general.



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

    Move Field


    A field is, or will be, used by another class more than the class on which it is defined.

    Create a new field in the target class, and change all its users.




    For more information see page 146 of Refactoring




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

    Move Class


    Refactoring contributed by Gerard M. Davison

    You have a class that is in a package that contains other classes that it is not related to in function.

    Move the class to a more relevant package. Or create a new package if required for future use.


    class org.davison.ui.TextThing
    class org.davison.ui.TextProcessor
    class org.davison.log.Logger

    depends on

    class org.davison.ui.StringUtil


    class org.davison.ui.TextThing
    class org.davison.ui.TextProcessor
    class org.davison.log.Logger

    depends on

    class org.davison.util.StringUtil

    Motivation



    Classes are often created in a packages close to where they are being used, this can make sense until the class starts to be re-used by other parts of the product. The package in question might also have just become too big. (I have a preference that my packages never have more than about 10 classes)

    It is often better to move to this class to a package more related to it in form or function. This can help remove complex package level dependencies and make it easier for developers to find and re-use classes.

    If there are many dependencies for the class within its own package, then Extract Class could be used first to split out the relevant parts.

    Another example where is this used often is to move String resource objects into sub a res package to simplify localization compilation.

    Mechanics



    • Move the class to its new folder on the source tree.

    • Remove any class files generated from compiling this class at its old location.

    • Alter the package statement in the source file to reflect the new package.

    • Create import statements for any dependant classes in original package.

    • Compile and test the class in its new package, updating and moving unit tests as required using this same method.

    • Alter, and create in some cases, the import statements on any dependee class. Note this is easier if wide imports are not used.

    • Check for classes that might dynamically instantiate this class using java.lang.reflect or the ResourceBundle api. Also look for code that might reference this class as an absolute class literal.

    • Compile and test all code that was dependant on the original class.

    • Consider applying
      Extract Package
      when you have many classes of different functionality in a given package.



    Example



      Lets look at the header of StringUtil


      package org.davison.ui

      // imports

      public class StringUtil

      ...

      We move the file and change the package header.


      package org.davison.util

      // imports

      public class StringUtil

      ...

      I can now compile and unit test this class in its new package. If the unit tests are in a different package class file then they might need to be updated.

      I can now go on to update the dependant classes. For example here I update the import statements, I have not used a wide imports in this example but the principle is the same.


      package org.davison.log

      // imports

      import org.davison.ui.StringUtils;

      // more imports

      public class Logger

      ...


      This becomes:


      package org.davison.log

      // imports

      import org.davison.util.StringUtils;

      // more imports

      public class Logger

      ...



      Again compile and test this new class with the imports.

      As mentioned before there are other ways of dynamically loading classes. You may have to look for class literals and strings constants containing the fully qualified name of the old class.




      // A class literal

      public Class m_utils = org.davison.ui.StringUtils.class;

      // A dynamically loaded class

      public Class m_utils = Class.forName("org.davison.ui.StringUtils");

      // A loaded resource bundle

      public ResourceBundle m_bundle = ResourceBundle.getBundle(
         "org.davison.ui.StringUtils");




      These can be fixed using simple find and replaces, these dynamic examples will also be found using the units tests for all classes.





      // A class literal, this will be found by the compiler.

      public Class m_utils = org.davison.util.StringUtils.class;

      // A dynamically loaded class

      public Class m_utils = Class.forName("org.davison.util.StringUtils");

      // A loaded resource bundle

      public ResourceBundle m_bundle = ResourceBundle.getBundle(
         "org.davison.util.StringUtils");





      One all static and dynamic cases have been dealt with, and all unit tests have run. The refactoring is complete.


    Additional Comments


    Consider using a tool to do this. See Chris Sequin's refactory or Woodenchair

    --Martin Fowler




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

    Move Business Logic to Session


    Inter-entity bean relationships introduce overhead in the model

    Encapsulate the workflow related to inter-entity bean relationships in a session bean (Session Facade)


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




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

    Merge Session Beans


    Create a one-to-one mapping between session beans and entity beans

    Map coarse-grained business services to session beans. Eliminate or combine session beans that act solely as entity bean proxies into session beans that represent coarse grained business services


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




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

    Localize Disparate Logic


    Business logic and presentation formatting are intermingled within a JSP view

    Extract business logic into one or more helper classes that can be used by the JSP or by a controller


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




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

    http://www.refactoring.com/catalog/introduceSynchronizerToken.html



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

    BLOG main image

    카테고리

    분류 전체보기 (539)
    이야기방 (19)
    토론/정보/사설 (16)
    IBM Rational (9)
    U-IT (0)
    SOA/WS/ebXML (110)
    개발방법론/모델링 (122)
    UML (4)
    XP/TDD (1)
    RUP (0)
    Agile Programming (1)
    Others (14)
    Testing (2)
    Unit Test (1)
    POSA (1)
    Architecture (1)
    Patterns (1)
    Refactoring (96)
    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 :