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

  1. 2003.08.02 Introduce Parameter Object <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  2. 2003.08.02 Introduce Null Object
  3. 2003.08.02 Introduce Local Extension <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  4. 2003.08.02 Introduce Foreign Method
  5. 2003.08.02 Introduce Explaining Variable
  6. 2003.08.02 Introduce Business Delegate (Link only)
  7. 2003.08.02 Introduce Assertion
  8. 2003.08.02 Introduce A Controller (Link only)
  9. 2003.08.02 Inline Temp
  10. 2003.08.02 Inline Method
  11. 2003.08.02 Inline Class
  12. 2003.08.02 Hide presentation tier-specific details from the business tier (Link only)
  13. 2003.08.02 Hide Method
  14. 2003.08.02 Hide Delegate
  15. 2003.08.02 Form Template Method
  16. 2003.08.02 Extract Superclass
  17. 2003.08.02 Extract Subclass
  18. 2003.08.02 Extract Package (by Gerard M. Davison) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  19. 2003.07.29 Extract Method
  20. 2003.07.29 Extract Interface
  21. 2003.07.29 Extract Class
  22. 2003.07.29 Encapsulate Field
  23. 2003.07.29 Encapsulate Downcast
  24. 2003.07.29 Encapsulate Collection
  25. 2003.07.29 Eliminate Inter-Entity Bean Communication (Link only)
  26. 2003.07.29 Decompose Conditional
  27. 2003.07.29 Convert Static to Dynamic Construction (by Gerard M. Davison) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  28. 2003.07.29 Convert Dynamic to Static Construction (by Gerard M. Davison) <IMG SRC = "http://www.refactoring.com/catalog/new.gif" border=0>
  29. 2003.07.29 Consolidate Duplicate Conditional Fragments <IMG SRC = "http://www.refactoring.com/catalog/updated.gif" border=0>
  30. 2003.07.29 Consolidate Conditional Expression

Introduce Parameter Object


You have a group of parameters that naturally go together.

Replace them with an object.



For more information see page 295 of Refactoring


Additional Comments


Dealing with a chain of calls


Ralph Johnson pointed out to me that a common case isn't clear in the Refactoring book. This case is when you have a bunch of methods that call each other, all of which have a clump of parameters that need this refactoring. In this case you don't want to apply Introduce Parameter Object because it would lead to lots of new objects when you only want to have one object that's passed around.

The approach to use is to start with the head of the call chain and apply Introduce Parameter Object there. Then apply

Preserve Whole Object
to the other methods.




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

Introduce Null Object



You have repeated checks for a null value.

Replace the null value with a null object.


                        if (customer == null) plan = BillingPlan.basic();
                        else plan = customer.getPlan();



For more information see page 260 of Refactoring




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

Introduce Local Extension



A server class you are using needs several additional methods, but you can't modify the class.

Create a new class that contains these extra methods. Make this extension class a subclass or a wrapper of the original.




For more information see page 164 of Refactoring

Additional Comments


Using Free Functions in C++


--Andy Glew writes:

I comment on this in the light of the recent comp.lang.c++.moderated discussion of using object.method() or free functions,
possibly friends, in a class interface. I.e. this comment is
more C++ oriented than Java oriented.

Briefly, if the original class used free functions for this sort
of interface, the assymmetry introduced by wrapping a class's
object.methods() would not exist.  In C++

    class MfDateSub {
        private: Date _original;
        // wrapping the symmetric operator after(date1,date2)
        public:  friend bool after (MfDateSub arg1, MfDateSub arg2) {
            return after(arg1._original,arg2._original);
        }
        public:  friend bool after (MfDateSub arg1, Date arg2) {
            return after(arg1._original,arg2);
        }
        public:  friend bool after (Date arg1, MfDateSub arg2) {
            return after(arg1,arg2._original);
        }
   };

Now all combinations work; the wrapping is more invisible to the user.

Even better if the free function after(date1,date2) does not require friendship --- although the definition of the extensions gets spread
into a few more places.

Note that in the example above, however, an implicit conversion of a MfDateSub value to a Date would suffice.

    class MfDateSub {
            operator Date() const { return _original }
    }

although this approach cannot always work, e.g. when there
is extra data to be compared in the extension.

CONCLUSION: using free functions in an interface allows a greater
degree of syntactic transparency when wrapping.

Return type for extra methods


--Dmitri Colebatch wrote in to ask why when using the subclass I didn't return the subclass in the extra methods. So I have added the nextDay method to MfDate, but it returns a Date not an MfDate. I can't think of any good reason to return the superclass, so I agree with him and suggest returning MfDate instead. The same is true for the wrapper implementation as well. After all if the client is using the extra method, they are aware of the new class. This way they avoid having to futz with the returned object if they want to invoke other extension methods.




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

Introduce Foreign Method



A server class you are using needs an additional method, but you can't modify the class.

Create a method in the client class with an instance of the server class as its first argument.


Date newStart = new Date (previousEnd.getYear(), previousEnd.getMonth(), previousEnd.getDate() + 1);



Date newStart = nextDay(previousEnd);

private static Date nextDay(Date arg) {
        return new Date (arg.getYear(),arg.getMonth(), arg.getDate() + 1);
}

For more information see page 162 of Refactoring




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

Introduce Explaining Variable



You have a complicated expression.

Put the result of the expression, or parts of the expression, in a temporary variable with a name that explains the purpose.

        if ( (platform.toUpperCase().indexOf("MAC") > -1) &&
              (browser.toUpperCase().indexOf("IE") > -1) &&
              wasInitialized() && resize > 0 )
        {
              // do something
        }

        final boolean isMacOs     = platform.toUpperCase().indexOf("MAC") > -1;
        final boolean isIEBrowser = browser.toUpperCase().indexOf("IE")  > -1;
        final boolean wasResized  = resize > 0;

        if (isMacOs && isIEBrowser && wasInitialized() && wasResized)
        {
                // do something
        }

For more information see page 124 of Refactoring




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

Introduce Business Delegate


Session beans in the business tier are exposed to clients in other tiers

Use a business delegate to decouple the tiers and to hide the implementation details

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



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

Introduce Assertion


A section of code assumes something about the state of the program.

Make the assumption explicit with an assertion.

        double getExpenseLimit() {
                // should have either expense limit or a primary project
                return (_expenseLimit != NULL_EXPENSE) ?
                        _expenseLimit:
                        _primaryProject.getMemberExpenseLimit();
        }


        double getExpenseLimit() {
                Assert.isTrue (_expenseLimit != NULL_EXPENSE || _primaryProject != null);
                return (_expenseLimit != NULL_EXPENSE) ?
                        _expenseLimit:
                        _primaryProject.getMemberExpenseLimit();
        }

For more information see page 267 of Refactoring



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

Introduce A Controller


Control logic is scattered throughout the application, typically duplicated in multiple Java Server Page (JSP) views

Extract control logic into one or more controller classes that serve as the initial contact point for handling a client request


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




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

Inline Temp



You have a temp that is assigned to once with a simple expression, and the temp is getting in the way of other refactorings.

Replace all references to that temp with the expression.

                double basePrice = anOrder.basePrice();
                return (basePrice > 1000)

                return (anOrder.basePrice() > 1000)

For more information see page 119 of Refactoring




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

Inline Method



A method's body is just as clear as its name.

Put the method's body into the body of its callers and remove the method.


        int getRating() {
                return (moreThanFiveLateDeliveries()) ? 2 : 1;
        }
        boolean moreThanFiveLateDeliveries() {
                return _numberOfLateDeliveries > 5;
        }



        int getRating() {
                return (_numberOfLateDeliveries > 5) ? 2 : 1;
        }


For more information see page 117 of Refactoring




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

Inline Class



A class isn't doing very much.

Move all its features into another class and delete it.



For more information see page 154 of Refactoring




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

Hide presentation tier-specific details from the business tier


Request handling and/or protocol-related data structures are exposed from the presentation tier to the business tier

Remove all references to request handling and protocol-related presentation tier data structures from the business tier. Pass values between tiers using more generic data structures.


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




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

Hide Method



A method is not used by any other class.

Make the method private.


For more information see page 303 of Refactoring




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

Hide Delegate



A client is calling a delegate class of an object.

Create methods on the server to hide the delegate.


For more information see page 157 of Refactoring




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

Form Template Method


You have two methods in subclasses that perform similar steps in the same order, yet the steps are different.


Get the steps into methods with the same signature, so that the original methods become the same. Then you can pull them up.

        
For more information see page 345 of Refactoring




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

Extract Superclass


You have two classes with similar features.

Create a superclass and move the common features to the superclass.



For more information see page 336 of Refactoring



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

Extract Subclass


A class has features that are used only in some instances.


Create a subclass for that subset of features.




For more information see page 330of Refactoring



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

Extract Package


Refactoring contributed by  Gerard M. Davison


A package either has too many classes to be easily understandable or it suffers from the 'Promiscuous packages' smell.


Extract a sub package depending on their gross dependencies or usages.


interface org.davison.data.DataProvider
class org.davison.data.DataFactory
// Database classes
class org.davison.data.JDBCProvider
class org.davison.data.JDBCHelper
class org.davison.data.JDBCUtils




interface org.davison.data.DataProvider
class org.davison.data.DataFactory
// Database classes
class org.davison.data.jdbc.JDBCProvider
class org.davison.data.jdbc.JDBCHelper
class org.davison.data.jdbc.JDBCUtils

Motivation


Dependencies will eventually cause problem in projects of any size, so it make sense to start refactoring sooner rather than later in order to make it clear which part of the code uses what.

This sort of change can make the code more flexible. For example if you are writing a UI tool and then decide a command line variant is required. Then unless the code is properly structured you will have trouble re-using certain components. Packaging is one way of making dependencies explicit.

This refactoring can be useful when a package becomes too large to be easily understood. For example in a diagrammer framework you might like to extra sub packages for important groups such as 'shapes'; 'ui' and 'printing'. This makes it easier to identify the use of a class by its implied association in a package.

The structure produced here is also one that is recommeneded for use with the Abstract Factory pattern. Indeed this is how the example I have provided is structured.

Mechanics



  • Work out groupings for your classes. Where required use the
    Extract Superclass
      to pull together any generic code first.

  • Create the new package and perform  
    Move Class
    for each file that needs to be moved. It is often efficient to move groups of classes at once.

  • Compile the code in the parent package and retest. The code in the sperate package will have been tested as part of the
    Move Class
    refactoring.

  • The refactorings at this point can be considered complete.

  • You might like to convert the code in the factory to using dynamic class loading by using the
    Convert Static to Dynamic Construction
    . This would enable selective inclusion of sub-packages depending on the build environment.


Example


    There are no code examples as most of the work in done in
    Move Class
    .

Additional Comments


The way I've done this is to move all the classes in one go. (I'm prepared to take the big step first here since all the errors can be found with compiling.)

I ensure the original package is dependent on the extracted package but the extracted package is independent of the original. Once I've done the move I compile the original package. The errors here can be fixed with import statements in the offending classes. I fix these errors until the original package compiles

Then I work on the extracted package. This may compile fine, the problem lies if you have a class in the extracted package referring to a class in the original package. I move it back if I can. If not I use
Extract Interface
to create an interface which captures the way the classes in the extracted pacakge refer to the original class. I then place the extracted interface in the extracted package.

--Martin Fowler




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

Extract Method



You have a code fragment that can be grouped together.

Turn the fragment into a method whose name explains the purpose of the method.

        void printOwing() {
                printBanner();

                //print details
                System.out.println ("name:        " + _name);
                System.out.println ("amount        " + getOutstanding());
        }




        void printOwing() {
                printBanner();
                printDetails(getOutstanding());
        }

        void printDetails (double outstanding) {
                System.out.println ("name:        " + _name);
                System.out.println ("amount        " + outstanding);
        }

For more information see page 110 of Refactoring





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

Extract Interface



Several clients use the same subset of a class's interface, or two classes have part of their interfaces in common.

Extract the subset into an interface.



For more information see page 341 of Refactoring





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

Extract Class



You have one class doing work that should be done by two.

Create a new class and move the relevant fields and methods from the old class into the new class.



For more information see page 149 of Refactoring




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

Encapsulate Field



There is a public field.

Make it private and provide accessors.

public String _name




private String _name;
public String getName() {return _name;}
public void setName(String arg) {_name = arg;}

For more information see page 206 of Refactoring





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

Encapsulate Downcast



A method returns an object that needs to be downcasted by its callers.

Move the downcast to within the method.

Object lastReading() {
        return readings.lastElement();
}




Reading lastReading() {
        return (Reading) readings.lastElement();
}

For more information see page 308 of Refactoring





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

Encapsulate Collection



A method returns a collection.

Make it return a read-only view and provide add/remove methods.


For more information see page 208 of Refactoring





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

Eliminate Inter-Entity Bean Communication



Inter-entity bean relationships introduce overhead in the model

Reduce or eliminate the inter-entity bean relationships by using coarse-grained entity bean (Composite Entity) with dependent objects

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



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

Decompose Conditional



You have a complicated conditional (if-then-else) statement.

Extract methods from the condition, then part, and else parts.

                if (date.before (SUMMER_START) || date.after(SUMMER_END))
                        charge = quantity * _winterRate + _winterServiceCharge;
                else charge = quantity * _summerRate;




                if (notSummer(date))
                        charge = winterCharge(quantity);
                else charge = summerCharge (quantity);

For more information see page 238 of Refactoring





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

Convert Static to Dynamic Construction


Refactoring contributed by Gerard M. Davison


You have classes that have static compile time dependencies on classes that can only be built on a specific platform.


Make use of the java.lang.reflect to break the static dependency.



   import org.davison.data.jdbc.JDBCProvider;

   .
   .
   .


   DataProvider dp = new JDBCProvider();




   try
   {
      DataProvider dp = (DataProvider)
         Class.forName("org.davison.data.jdbc.JDBCProvider").newInstance();
   }
   catch (IllegalAccessException iae)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new IllegalAccessError(iae.getMessage());
   }
   catch (InstantiationException ie)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new InstantiationError(ie.getMessage());      
   }
   catch (ClassNotFoundException cnfe)
   {
      // Convert exception to error to preseve the interface.
      //

      throw new NoClassDefFoundError(cnfe.getMessage());
   }


Motivation


In some cases you have to provide drivers to provide different functionality depending on the situation. You might have classes that on a given platform need to access some sun.* classes to perform a specific function. For example a class to access WinHelp needs to get the window handle via the sun.awt.windows.WWindowPeer classes.

There might also be the desire to only provide certian functionality to a given sub-set of users. This is the equivalent of being able to compile out code without having to alter the source or use pre-compilers.

This method can be used with good effect with application frameworks where you do not know which class need to be used at compile time.

Mechanics


- Identify the place where the different classes are instantiated. If there is more than one place, you might like to make use of code consolidation refactorings to create one entry point.
- Make sure that there is a common interface and method of construction. Utilise Extract Interface or use Extract Superclass to create a suitable abstraction to work with.
- Replace the class selection process with one that instead selects for the string name of the class in question.
Remove any import statements that refere the the classes being constructed.
- Add code in to load and instantiate the class. For more parameterised contructors, make use of the java.lang.reflect package.
- Deal with any excpetion generated.
- You are now ready to compile and test the code. Make sure that any dependant code is also tested properly.
- The refactoring is complete, but you should make sure that this run-time dependency is properly documented and that all developers know to instantiate the classes using the new or altered method.

Example


Start with this code:


   import org.davison.data.jdbc.JDBCProvider;

   .
   .
   .

   DataProvider dp = new JDBCProvider();



First we have to change the selection code to return a class name rather than an actual instance. We can safely remove the import statement that referes to this class.


   Class.forName("org.davison.data.jdbc.JDBCProvider")


We can now instantiate the class, in this simple case the constructor has no parameters, so we do not have to make use of the extended java.lang.reflect package.



      DataProvider dp = (DataProvider)
         Class.forName("org.davison.data.jdbc.JDBCProvider").newInstance();



We no have to add the code to deal with the possible exception cases. Here I have chosen to convert them to the equivalent Java Errors in order to maintain the interface. If this is not required then simpler code is possible.



   try
   {
      DataProvider dp = (DataProvider)
         Class.forName("org.davison.data.jdbc.JDBCProvider").newInstance();
   }
   catch (IllegalAccessException iae)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new IllegalAccessError(iae.getMessage());
   }
   catch (InstantiationException ie)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new InstantiationError(ie.getMessage());      
   }
   catch (ClassNotFoundException cnfe)
   {
      // Convert exception to error to preseve the interface.
      //

      throw new NoClassDefFoundError(cnfe.getMessage());
   }



Compile and test at this point as we have code that is complete.

When this is finished and all dependent classes are re-tested, the refactoring is complete.





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

Convert Dynamic to Static Construction


Refactoring contributed by Gerard M. Davison


You have code that loads other classes dynamically. This can introduce a un-waranted overhead and can produce code that is more fragile.


Replace the dynamic class loading with static code.


   try
   {
      DataProvider dp = (DataProvider)
         Class.forName("org.davison.data.jdbc.JDBCProvider").newInstance();
   }
   catch (IllegalAccessException iae)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new IllegalAccessError(iae.getMessage());
   }
   catch (InstantiationException ie)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new InstantiationError(ie.getMessage());      
   }
   catch (ClassNotFoundException cnfe)
   {
      // Convert exception to error to preseve the interface.
      //

      throw new NoClassDefFoundError(cnfe.getMessage());
   }



   import org.davison.data.jdbc.JDBCProvider;

   .
   .
   .
  
   DataProvider dp = new JDBCProvider();



Motivation


In some cases code is written with dynamic dependencies between parts of the code by utilising Java ability to load and instantiate arbitrary classes. If not properly managed, this can cause run-time errors. This design can impart a performance penalty because of the extra levels of indirection. It can also prevent the compiler from detecting certian types of error.

Mechanics


- Identify the places where the different classes are instantiated. If there is more than one place, you might like to make use of code consolidation refactorings to create one entry point.
- You can remove the code that instantiates the classes using java.lang.reflect. We will instead call the constructors directly.
Replace the code that selects the name of the class with simpler code that simply returns a new instance.
- Add in import statements as required for the classes being constructed.
- You are now ready to compile and test the code. Make sure that any dependant code is also tested properly.
- The refactoring is complete.

Example


Start with this code:

   try
   {
      DataProvider dp = (DataProvider)
         Class.forName("org.davison.data.jdbc.JDBCProvider").newInstance();
   }
   catch (IllegalAccessException iae)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new IllegalAccessError(iae.getMessage());
   }
   catch (InstantiationException ie)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new InstantiationError(ie.getMessage());      
   }
   catch (ClassNotFoundException cnfe)
   {
      // Convert exception to error to preseve the interface.
      //

      throw new NoClassDefFoundError(cnfe.getMessage());
   }



We can remove the error handling code and simply instantiate the class.



   DataProvider dp = new JDBCProvider();
  


The final step is to add in the correct import statement


   import org.davison.data.jdbc.JDBCProvider;

   .
   .
   .
  
   DataProvider dp = new JDBCProvider();
  


Compile and test at this point as we have code that is complete.

When this is finished and all dependent classes are re-tested, the refactoring is complete.

Another way of creating compile time dependencies is to use class literals. This would still have the overhead of dynamic instantiation. I would not recommend this unless you have good reason; but here is the code converted to use this method.




   try
   {
      DataProvider dp = (DataProvider)
         org.davison.data.jdbc.JDBCProvider.class.newInstance();
   }
   catch (IllegalAccessException iae)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new IllegalAccessError(iae.getMessage());
   }
   catch (InstantiationException ie)
   {
      // Convert exception to error to preseve the interface.
      //
      
      throw new InstantiationError(ie.getMessage());      
   }
   catch (ClassNotFoundException cnfe)
   {
      // Convert exception to error to preseve the interface.
      //

      throw new NoClassDefFoundError(cnfe.getMessage());
   }





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

Consolidate Duplicate Conditional Fragments



The same fragment of code is in all branches of a conditional expression.

Move it outside of the expression.

                if (isSpecialDeal()) {
                        total = price * 0.95;
                        send();
                }
                else {
                        total = price * 0.98;
                        send();
                }




                if (isSpecialDeal())
                        total = price * 0.95;
                else
                        total = price * 0.98;
                send();

For more information see page 243 of Refactoring

Additional Comments


Using with try/catch blocks

Paul Haahr rightly took me to task for being far too glib when I talked about consolidating with exceptions. You can only pull repeated code into a final block if all non-fatal exceptions are caught. This is because the finally block is executed after any exception, including those that don't have a catch clause. (Of course you may prefer that to happen, but that's not a semantics preserving change.)

Contributors


- Paul Haahr




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

Consolidate Conditional Expression



You have a sequence of conditional tests with the same result.

Combine them into a single conditional expression and extract it.

        double disabilityAmount() {
                if (_seniority < 2) return 0;
                if (_monthsDisabled > 12) return 0;
                if (_isPartTime) return 0;
                // compute the disability amount



        double disabilityAmount() {
                if (isNotEligableForDisability()) return 0;
                // compute the disability amount

For more information see page 240 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)
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 :