1
\$\begingroup\$

So say I have a method that does a bunch of stuff, and I want to refactor this method to take a different type of parameter:

public object A(MyObject a)
{
    // does a bunch of crap with a

    // then calls another method
    this.B(a);
}

Now even method B() does a lot of crap with that same Object a. What if I want an endpoint that takes a SecondObject b. What I just did was basically duplicate all the methods and change the parameter type, but now I'm sitting with basically a bunch of duplicate code here. What's the best way to refactor this so that all my methods can take a different set (not just a different type) of parameters and reduce duplicity?

Thanks.

Edit:

Example,

private Chatham.Panda.WCF.DataContracts.IInstrument FillHistoricInstrumentRates(
            Chatham.Panda.WCF.DataContracts.IInstrument instrument,
            Chatham.Enumerations.BidMidAsk valuationPrice,
            DateTime rateCutoffDate,
            bool loadRates,
            FillInstrumentRates recursiveDelegate)
        {
            if (instrument == null)
            {
                throw new ArgumentNullException(
                    "instrument",
                    "RateAcqusitionService.SetInstrumentHistRates's 'instrument' argument is null");
            }

            // Compound Instruments
            Chatham.Panda.WCF.DataContracts.CompoundInterestRateInstrument compoundInstrument =
                instrument as Chatham.Panda.WCF.DataContracts.CompoundInterestRateInstrument;

            if (compoundInstrument != null)
            {
                foreach (Chatham.Panda.WCF.DataContracts.IInstrument i in compoundInstrument.ChildInstruments)
                {
                    recursiveDelegate(i);

                    return compoundInstrument;
                }
            }

            // Simple Instruments
            Chatham.Panda.WCF.DataContracts.SimpleInterestRateInstrument simpleInstrument =
                instrument as Chatham.Panda.WCF.DataContracts.SimpleInterestRateInstrument;

            if (simpleInstrument != null)
            {
                // Set Rates for each Component
                foreach (Chatham.Panda.WCF.DataContracts.Component component in simpleInstrument.Components)
                {
                    this.FillHistoricComponentRates(
                        component,
                        valuationPrice,
                        rateCutoffDate,
                        loadRates
                        );
                }

                return instrument;
            }

            throw
                new NotSupportedException(
                    string.Format(
                        "Instrument with type '{0}' currently not supported",
                        instrument.GetType().FullName)
                    );
        }

Now I want to change this method so that it takes a List<ScheduleRow> rows, as well as some other random properties including within the Chatham.Panda.WCF.DataContracts.IInstrument instrument, instead of passing the whole instrument across the wire, but if I just create another method with all this code in it and different parameters, it won't look TOO much different, and have plenty of duplicate code.

Then I'd also be doing things like calling:

this.FillHistoricComponentRates(
                            component,
                            valuationPrice,
                            rateCutoffDate,
                            loadRates
                            );

With a list of rows instead of the entire component, which leads to THAT method being changed in the same exact fashion, so on and so on...

\$\endgroup\$
  • \$\begingroup\$ Is simpleInstrument merely a base case of the CompoundInstrument? If so the RecursiveDelegate is not written properly as any recursive method naturally must handle it's base case. And RecursiveDelegate signature would change to pass along those other parameters. If the type & number of parameters is still indeterminate perhaps create a class who's sole purpose is to have a property for every potential parameter. \$\endgroup\$ – radarbob Jan 22 '12 at 22:43
  • \$\begingroup\$ It's hard to say from the example, but I feel like the FillHistoricInstrumentRates method might belong as a method on a common base class of SimpleInterestRateInstrument and CompoundInterestRateInstrument. The common logic can stay in that method, but differences could possibly be addressed by adding protected abstract methods; SimpleInterestRateInstrument and CompoundInterestRateInstrument would need to provide the appropriate implementations for those abstract methods. \$\endgroup\$ – Dr. Wily's Apprentice Jan 24 '12 at 19:15
1
\$\begingroup\$

If I understand your question correctly I would refactor your method by implementing the template pattern in an OO or functional way whatever suits you best. Look at this excellent article for more information on the two options http://www.codeproject.com/KB/architecture/TMDPvsLambda.aspx.

This you'll be able to avoid duplicating your code while still being able to have different behaviors.

|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

What you want to probably look at is

  1. Either Method Overloading orSimple Explanation & Example of Delegates
  2. Delegates or Anonymous delegates..
  3. Basic OO Concepts - Object Oriented Concepts Basic OO Concepts also your Method Names should be more descriptive
  4. Basic Design Patterns in C# Code Project Site Basic Design Patterns
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I know how to overload methods, but even with the method overload there is duplicate code. That's my main issue. \$\endgroup\$ – slandau Jan 20 '12 at 15:00
  • \$\begingroup\$ What about Delegates then..? \$\endgroup\$ – DJ KRAZE Jan 20 '12 at 15:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.