Replace Method with Method Object

Source: Internet
Author: User

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

02

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.

03

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

04

In this book I emphasize the beauty of small methods. By extracting pieces out of a large method, you make things much more comprehensible.

05

The difficulty in Decomposing a method lies in local variables. If they are rampant, decomposition can be difficult. usingreplace
Temp with Query helps to reduce this burden, but occasionally you may find you cannot break down a method that needs breaking. In this case you reach deep into the tool bag and get out your method
Object.

06

Applying Replace Method
With Method Object turns all these local variables into fields on the method object. You can then use Extract
Method on this new object to create additional methods that break down the original method.

Mechanics

07

Stolen shamelessly from Beck [Beck].

08

  • Create a new class, name it after the method.

  • Give the new class A final field for the object that hosted the original method (the source object) and a field for each temporary variable and each parameter in the method.

  • Give the new class A constructor that takes the source object and each parameter.

  • Give the new class A method named "compute ."

  • Copy the body of the original method into Compute. Use the source object field for any invocations of methods on the original object.

  • Compile.

  • Replace the old method with one that creates the new object and callcompute.

09

Now comes the fun part. Because all the local variables are now fields, you can freely decompose the method without having to pass any parameters.

Example

10

A proper example of this requires a long chapter, so I'm showing this Refactoring for a method that doesn't need it. (Don't ask what the logic of this method is, I made it up as I went along .)

11

//Class Accountint gamma (int inputVal, int quantity, int yearToDate) {    int importantValue1 = (inputVal * quantity) + delta();    int importantValue2 = (inputVal * yearToDate) + 100;    if ((yearToDate - importantValue1) > 100)        importantValue2 -= 20;    int importantValue3 = importantValue2 * 7;    // and so on...    return importantValue3 - 2 * importantValue1;}

12

To turn this into a method object, I begin by declaring a new class. I provide a final field for the original object and a field for each parameter and temporary variable in the method.

13

    //class Gamma...    private final Account _account;    private int inputVal;    private int quantity;    private int yearToDate;    private int importantValue1;    private int importantValue2;    private int importantValue3;

14

I usually use the underscore prefix Convention for marking fields. But to keep small steps I'll leave the names as they are for the moment.

15

I add a constructor:

16

Gamma (Account source, int inputValArg, int quantityArg, int yearToDateArg) {    _account = source;    inputVal = inputValArg;    quantity = quantityArg;    yearToDate = yearToDateArg;}

17

Now I can move the original method over. I need to modify any CALS of features of account to use_accountField

18

int compute () {    importantValue1 = (inputVal * quantity) + _account.delta();    importantValue2 = (inputVal * yearToDate) + 100;    if ((yearToDate - importantValue1) > 100)        importantValue2 -= 20;    int importantValue3 = importantValue2 * 7;    // and so on...    return importantValue3 - 2 * importantValue1;}

19

I then modify the old method to delegate to the method object:

20

int gamma (int inputVal, int quantity, int yearToDate) {    return new Gamma(this, inputVal, quantity, yearToDate).compute();}

21

That's the essential refactoring. The benefit is that I can now easily use Extract
Method on the compute method without ever worrying about the argument's passing:

22

int compute () {    importantValue1 = (inputVal * quantity) + _account.delta();    importantValue2 = (inputVal * yearToDate) + 100;    importantThing();    int importantValue3 = importantValue2 * 7;    // and so on...    return importantValue3 - 2 * importantValue1;} void importantThing() {    if ((yearToDate - importantValue1) > 100)        importantValue2 -= 20;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.