Exforsys
+ Reply to Thread
Results 1 to 3 of 3

How to organize-class/object relationship

This is a discussion on How to organize-class/object relationship within the Software Patterns forums, part of the Testing category; I have to construct a service that client programmers will use, eventually, client programmer can see the service through one ...

  1. #1
    ishijak Guest

    How to organize-class/object relationship

    I have to construct a service that client programmers will use,
    eventually, client programmer can see the service through one interface
    and one class that will create and return references to particular
    implementation of that interface.

    public interface Customer
    {
    // decreases the customer account by value of volume
    void getMoney(double volume)

    // increases the customer account by value of volume
    void putMoney(double volume)

    // returns unique customer id
    String id();
    }

    public class CustomerCreator
    {
    // creates particular impl. of the Customer based on id
    public Customer createCustomer(String id);

    public void destroy(Customer cust);
    }


    // handles Customer whose id's are "3[0-9].*"
    // This is a facade to subsystem that handles the group of these
    customers
    class CustomerImplOfType3 implements Customer
    {
    public void getMoney(double volume){}
    public void putMoney(double volume){}
    public String id(){}
    }


    // handles Customer whose id's are "7[0-9].*"
    // This is a facade to subsystem that handles the group of these
    customers
    class CustomerImplOfType7 implements Customer
    {
    public void getMoney(double volume){}
    public void putMoney(double volume){}
    public String id(){}
    }

    Based on "id" value, there are completely different
    ways(implementations) for handling customers and different subsystems
    are involved. CustomerCreator has to decide from which implementation
    to make instance. Customer implementations (Facades to subsystems) will
    increase over time and existing ones will change. Also I want to have
    possability to implement new CustomerImpls and to do not have to
    recompile neither the framework classes, neither the existing
    implementations (if they're still valid).
    CustomerCreator.createCustomer will throw "Notsupported" if there is no
    impelmentation that can handle given id.


    One approach is to create an array of prototypes of CustomerImpl, all
    of them will implement boolean canYouHandle(String id) and the
    CustomerCreator object shall iterate and ask every prototype, and to
    clone that one that will answer "yes(true)"

    So the implemenatation will look something like this:


    ---charging framework package---

    package chargingfw;

    // Client programmers will use this interface to manipulate the
    customers
    public interface Customer
    {
    // decreases the customer account by value of volume
    void getMoney(double volume);

    // increases the customer account by value of volume
    void putMoney(double volume);

    // returns unique customer id
    String id();
    }


    // subsystem programmers will use this interface to integrate
    subsystems in the application
    public interface CustomerFacadeBase extends Customer
    {
    public boolean canYouHandle(String id);
    public CustomerFacadeBase instance(String id);
    }

    public class CustomerCreator
    {
    ArrayList<CustomerFacadeBase> custPrototypes;

    public CustomerCreator(String[] listOfImpls)
    {
    for (each i in listOfImpls)
    {
    //load corresponding classes
    // create prototype instance
    custPrototypes.add(currenProto);
    }
    }


    // creates particular impl. of the Customer based on id
    Customer createCustomer(String id) throws Unsupported
    {
    for (each i in custPrototypes)
    {
    if (i.canYouHandle(id))
    return i.instance(id);
    }
    throw new Unsupported(id);
    }

    void destroy(Customer cust);
    }


    ---Subsystem3 Facade Implemenation package---

    // handles Customer whose id's are "3[0-9].*"
    // This is a facade to subsystem that handles these customers
    final class CustomerImplOfType3 implements CustomerFacadeBase
    {

    public CustomerImplOfType3(String id)
    {
    _id = id;
    init_subsystem();
    }

    public void getMoney(double volume){}
    public void putMoney(double volume){}
    public String id(){}

    public CustomerFacadeBase instance(String id)
    {
    return new CustomerImplOfType7(id);
    }


    public boolean canYouHandle(String id)
    {
    if (id like "3[0-9].*")
    return true;
    return false;
    }

    private Subsystem3 ss;

    }

    ---Subsystem7 Facade Implemenation package---

    // handles Customer whose id's are "7[0-9].*"
    // This is a facade to subsystem that handles these customers
    final class CustomerImplOfType7 implements CustomerFacadeBase
    {
    public CustomerImplOfType7(String id)
    {
    _id = id;
    init_subsystem();
    }

    public void getMoney(double volume) {}
    public void putMoney(double volume){}
    public String id(){}


    public CustomerFacadeBase instance(String id)
    {
    return new CustomerImplOfType7(id);
    }

    public canYouHandle(String id)
    {
    if (id like "7[0-9].*")
    return true;
    return false;
    }

    private Subsystem7 ss;
    String _id;
    }


    It would be better if only one object instance per customer exists in
    the application, and all manipulation to go through that inctance for
    particular customer.


    ---client code---

    // client code shall be multithreaded,

    import chargingfw;

    main()
    {
    String[] ssFacades = //subsystem facade class names
    CustomerCreator cr = new CustomerCreator(ssFacades);

    Customer cust = cr.createCustomer("3124455");
    cust.getMoney(10);
    ...
    ...
    cr.destroy(cust);

    }

    My questions are:
    Is this approach good?
    Any suggestions for better design?
    Issues?

    Thanks,
    Ivan Sijakovski




  2. #2
    Robert Klemme Guest

    Re: How to organize-class/object relationship


    "ishijak" <ishijak@gmail.com> schrieb im Newsbeitrag
    news:1107784849.988717.113990@c13g2000cwb.googlegroups.com...
    > I have to construct a service that client programmers will use,
    > eventually, client programmer can see the service through one interface
    > and one class that will create and return references to particular
    > implementation of that interface.
    >
    > public interface Customer
    > {
    > // decreases the customer account by value of volume
    > void getMoney(double volume)
    >
    > // increases the customer account by value of volume
    > void putMoney(double volume)
    >
    > // returns unique customer id
    > String id();
    > }
    >
    > public class CustomerCreator
    > {
    > // creates particular impl. of the Customer based on id
    > public Customer createCustomer(String id);
    >
    > public void destroy(Customer cust);
    > }
    >
    >
    > // handles Customer whose id's are "3[0-9].*"
    > // This is a facade to subsystem that handles the group of these
    > customers
    > class CustomerImplOfType3 implements Customer
    > {
    > public void getMoney(double volume){}
    > public void putMoney(double volume){}
    > public String id(){}
    > }
    >
    >
    > // handles Customer whose id's are "7[0-9].*"
    > // This is a facade to subsystem that handles the group of these
    > customers
    > class CustomerImplOfType7 implements Customer
    > {
    > public void getMoney(double volume){}
    > public void putMoney(double volume){}
    > public String id(){}
    > }
    >
    > Based on "id" value, there are completely different
    > ways(implementations) for handling customers and different subsystems
    > are involved. CustomerCreator has to decide from which implementation
    > to make instance. Customer implementations (Facades to subsystems) will
    > increase over time and existing ones will change. Also I want to have
    > possability to implement new CustomerImpls and to do not have to
    > recompile neither the framework classes, neither the existing
    > implementations (if they're still valid).
    > CustomerCreator.createCustomer will throw "Notsupported" if there is no


    > impelmentation that can handle given id.
    >
    >
    > One approach is to create an array of prototypes of CustomerImpl, all
    > of them will implement boolean canYouHandle(String id) and the
    > CustomerCreator object shall iterate and ask every prototype, and to
    > clone that one that will answer "yes(true)"
    >
    > So the implemenatation will look something like this:


    <snip/>

    > My questions are:
    > Is this approach good?
    > Any suggestions for better design?
    > Issues?


    If you have only a small set of sub systems, then I'd probably just have
    that many createCustomerTypeX(String id) methods and determine the
    appropriate method programmatically "if (id.startsWith("3") ... else
    if...".

    If it's more complex I'd have a factory for each subsystem and class
    CustomerCreator (better CustomerFactory) just delegates to the appropriate
    subsystem factory; the simplest approach would be to just iterate through
    all factories and ask each in turn whether it feels like handling this
    particular id (for creation) or instance (for deletion).

    You might also consider to put the delete method into the Customer
    interface because the customer can easily know its factory. Drawback is a
    certain degree of asymmetry between creation and deletion.

    Kind regards

    robert




  3. #3
    kurbylogic@hotmail.com Guest

    Re: How to organize-class/object relationship

    I think that is a reasonable approach.

    Another option you might concider is meta data.
    Instead of i.canYouHandle(String Id)
    you could use configuration files to associate an id or pattern with a
    typename.
    <customerTypes>
    <add pattern="3[0-9].*"
    typeName="CustomerImplOfType3"/>
    ...
    </customerTypes>

    This could also become a source of (mis)configuration errors so
    sometimes its not worth adding flexibility where it isn't needed.
    However in this case perhaps it is appropriate, expecially with "magic
    numbers." Today it is 3[0-9], but tomorrow when decide to convert all
    there existing data to use an alpha prefix instead it becomes C[0-9],
    not only do you have to modify the code its also distributed across
    many class files. If you decide it is so unlikely to change you would
    rather modify the source code than maintain config files then using a
    if/else/switch statements in the factory would at least centralize the
    type mapping functionality.
    canYouHandle does not seem complex enough in this scenario to
    distribute the function to the various individual objects. If logic
    begins to get more complex and/or seperate properties are used to
    determine membership than asking the object canYouHandle might be more
    appropriate, and you should make canYouHandle virtual so if it for
    example you find that 3[0-9]* is actually 3([0-9]|[A-Z])* you can
    simply replace this method instead of creating a new implementation.

    - Kurt




    •    Sponsored Ads



Latest Article

Network Security Risk Assessment and Measurement

Read More...