none
encapsulation with the factory method RRS feed

  • Question

  • Hi,

    I have the following class structure that follows the Factory Method


    Interface: Instrument

    Bond : Instrument
    Stock: Instrument
    Fund: Instrument
    .......


    Interface  InstrumentesCreator {
         Instrument Create(string ID);

    }

    BondCreator : InstrumentCreator
    StockCreator: InstrumentCreator
    FundCreator: InstrumentCreator



    When I need to create collection of Instruments, which I call portfolio I do sort of

    for i=1 to n
       if ( InstrumentType[ID] == "Bond")
             Portfolio.Add(BondCreator.Create(ID))
      else if (InstrumentType[ID] == "Stock")
             Portfolio.Add(StockCreator.Create(ID))
      else if ((InstrumentType[ID] == "Fund")
             Portfolio.Add(FundCreator.Create(ID))
      ........


    The problem is, if I need to add another instrument, I need to change this code.
    Is there a way to incapsulate it further? Am i missing something?
    My understanding was that the whole idea of the factory methods was to avoid this kind of (if else if else if....) structure in code.
    Thanks

    Pierpaolo


    • Edited by arguros Monday, August 24, 2009 7:32 AM
    Monday, August 24, 2009 7:32 AM

Answers

  • Hi,

    Why do the Creator need to get the ID as input parameter? To me it seems you are doing If ("Bond") then... BondCreator.Create("Bond")? BondCreator should know this already.

    Anyways, two possible solutions comes to mind:

    1) Put "BondCreator", "StockCreator" and "FundCreator" in a configuration file or database store. Then fetch these values into an array and do your loop. In the loop use reflection to get hold of an XXXXXCreator and do create (skip the input param). If you add values into the config it will automatically be in the for loop the next time.

    2) Add attributes to the classes Bond, Stock and Fund marking them as an Instrument. Then use reflection to get all classes with this attribute. Then do the looping and reflection to get the creator (string.conat(XXX, "Creator")).
    MCTS | MCPD
    • Marked as answer by arguros Friday, August 28, 2009 6:36 AM
    Tuesday, August 25, 2009 6:14 AM

All replies

  • Hi,

    Why do the Creator need to get the ID as input parameter? To me it seems you are doing If ("Bond") then... BondCreator.Create("Bond")? BondCreator should know this already.

    Anyways, two possible solutions comes to mind:

    1) Put "BondCreator", "StockCreator" and "FundCreator" in a configuration file or database store. Then fetch these values into an array and do your loop. In the loop use reflection to get hold of an XXXXXCreator and do create (skip the input param). If you add values into the config it will automatically be in the for loop the next time.

    2) Add attributes to the classes Bond, Stock and Fund marking them as an Instrument. Then use reflection to get all classes with this attribute. Then do the looping and reflection to get the creator (string.conat(XXX, "Creator")).
    MCTS | MCPD
    • Marked as answer by arguros Friday, August 28, 2009 6:36 AM
    Tuesday, August 25, 2009 6:14 AM
  • The idea is:

    Bond,Stock,Fund are all different kind of Instruments. In the DB there is a unique ID for each instrument. ID in this contest in the instrument Identifier, not the type identifier. So I can have many ID of type bond, stock, fund.  InstrumentType[ID] just look up in the DB and find out for me wich kind on Instument it is.  The Bond Class depends on a BondParameter class (which inherits from Parameter), and the BondCreator looks after it to fill its values when it create a Bond.
    A Portfolio can be made of many bond, stocks, funds.

    To be more precise:
    I can have
    1) Bond with Maturity in 3 years and coupon 2.5%
    2) Bond with Maturity in 0.5 years and coupon 0%
    ...
    10) Miscosoft Stock
    11) Google Stock
    ..
    18) JMP Fund Euro Growh
    19) GS Fund US value
    ------

    I just would like to loop of these insturment and create them as CreateInstument(ID), without modifying this function each time I add a new instrument

    So what I am really doing is If ("Bond") then ----- BondCreator.Create("An Instrument of type Bond for security ID= Id)


    May you give me a short example on how 1) or 2) works. I did not get how the two solution you are suggesting work?

    Many thanks

    Pierpaolo
    Tuesday, August 25, 2009 7:04 AM
  • So then it's simple, the solution is:

    BondCreator.Create(ID).

    You probably need to read up on the strategy pattern, as what you're effectively describing is a provider pattern (of which there are base classes in .NET 2.0)  This would be the approach that I would take.

    Alternatively, if you don't fancy that approach:

    Perhaps each instrument can report its ID, then the code simply walks through all available instruments, attempting to create if IDs match?

    The other thing is that each Instrument could have a method that you call 'IsMatched(ID)' where each implementation either does a string compare, or a regex match to find if it should be instantiated.  This muddies the waters a little, since I don't really like the style of having the implementation matching done in the implementation, but it is an approach.


    I hope this helps,

    Martin.

    MCSD, MCTS, MCPD. Please mark my post as helpful if you find the information good!
    Tuesday, August 25, 2009 9:20 PM