3

I need to build a class which makes use of method chaining. I understand the concept of method chaining. Example:

class Company
{
    private String companyName;
    public setCompanyName(String companyName)
    {
        this.companyName = companyName;
        return this;
    }

    public Person addPerson(String name)
    {
         person = new Person();
         person.setName(name);

         return person;
    }
}

class Person
{
    private String name;
    private String address;
    private bool license

    public Person setName(String name)
    {
        this.name = name;
        return this;
    }

    public Person hasDriverLicense(bool license)
    {
        this.license = license;
        return this;
    }

    public Person setAddress(String address)
    {
        this.address = address;
        return this;
    }
}

//in some other class / method i do:
Company company = new Company()
.setCompanyName("SomeCompany")
.addPerson("Mike")
.setAddress("Street 118");

But i need to take this one step further. I need to be able to do this:

Company company = new Company()
.setCompanyName("SomeCompany")
.addPerson("Mike")
.setAddress("Street 118");
.addPerson("Jane")
.setAddress("Street 342");
.hasDriverLicense(true)

So as you can see i need to be able to continue with chaining. The method addAddress isn't always the last method in the chain. It can be any method from the Person class.

Is there a good way to achieve this functionality? Perhaps with method extensions or something?

Any help / examples are greatly appreciated.

w00
  • 26,172
  • 30
  • 101
  • 147
  • 5
    I have to ask... *why* do you want this all to be one continuous serious of methods? can't you just store the company and call addPerson from that several times? `var company = ...; company.addPerson(...).setAddress(...); company.addPerson(...).setAddress(...);` ? – Marc Gravell Aug 30 '12 at 13:47
  • 2
    or even better... just object/collection initializers? `var company = new Company { Name = "SomeCompany", People = { new Person {Name = Mike", Address = "Street 118"}, new Person {Name="Jane", Address = "Street 342", HasDriverLicence = true}}};` (that would look prettier in an IDE than it does all squashed into one comment!) – Marc Gravell Aug 30 '12 at 13:51

1 Answers1

3

You can do it. Which dos not imply that you should:

The methods of Person and Company should simply return an object that aggregates the person and the company in the context. If you have an IPerson interface and ICompany interface, this type will implement both, hold references to both internally and will dispatch the calls appropriately. (Calls to IPerson method will be delegated to the internal IPerson).

That being said, I would strongly discourage you from taking this path. It is confusing, very hard to Debug and violates basic OO principles (e.g. Interface Segregation).

Vitaliy
  • 8,044
  • 7
  • 38
  • 66
  • 2
    Thanks, because of you and the comments that i got i am now certain that i should take a different approach. – w00 Aug 30 '12 at 14:17