1

I have two classes that read distinct files. As an examples, two classes, sourceA or Client, and sourceB or Resources:

public class Client()
{
    public string ClientName {get; set;}
    public int ClientNumber {get; set;}
    public string Address {get; set;}
    //...
}

public class Resources()
{
    public int ClientNumber {get; set;}
    public decimal Resources {get; set;}
    //...
}

Let's say that I need to merge booth classes into a new one, but I just need some fields from class Client and Resources. Is there any software pattern motivated by something like this, to compose a class like ClientReport?

The new class should be something like this:

public class ClientReport()
{
    public string ClientName {get; set;}
    public int ClientNumber {get; set;}
    public string Address {get; set;}
    public decimal Resources {get; set;}

    public int CalculateRating()
    {
        //...
    }
}

These new classe will have some properties of Client and Resources, and copying code from them in order to create ClientReport seems to be a repetition, and I think it should be a away to compose this class and only use the needed properties from Client and Resources.

8
  • 1
    What do you mean by "merge into a new one"? Will the two classes continue to exist? If so, how exactly are they related to the new class? A description of the context and business logic would be good because the answer will probably depend on it.
    – valenterry
    May 5, 2015 at 16:09
  • 4
    Generally no. This sort of "we need some of A and some of B" is usually motivated by garbage business requirements. You should avoid it if possible, not patternize it.
    – Telastyn
    May 5, 2015 at 16:11
  • Hum, lets say you have two lists: List<sourceA>, List<sourceB>, both classes have a high number of properties for handling the reading of files. Then you need to combine the information from the two lists, therefore generating a new object of a class C. In that away you combine objects from A and B.
    – cap7
    May 5, 2015 at 16:16
  • It might help us understand what you mean if you gave us a concrete example.
    – MetaFight
    May 5, 2015 at 16:17
  • 2
    Composition by Facade Pattern
    – user7519
    May 5, 2015 at 16:41

3 Answers 3

2

Here are (at least) two objects client and report involved. From what you write so far, a report seems best to be composed of a client and ressources:

public class ClientReport()
{
    public Client client;
    public decimal ressources;

    public getClientName(){ return this.client.getName(); }
    // ...
    public setRessources(decimal ressources){ this.ressources=ressources; }

    public ClientReport(Client client){
        this.client=client;
    }
}

Instead of copying the fields of the Client you should wrap the Client into the ClientReport (pass it via constructor) and delegate incoming calls of the report to the Client itself (see getClientName()). So you are free to hide/show (= encapsulate), whatever part of the Client you want. It makes sense to hide the creation of the ClientReport behind a Builder. The Builder reads first SourceA to generate the List<Clients>. After that it reads SourceB to map the ressources to the respective client. The Builder itself has only one method getClientReports(), which does all that transparently to the consumer.

You should further clean up your object design. Perhaps it makes sense in your domain to have an Address-object, which is wrapped by the Client object.

2
  • Your answer is very useful, and my code right looks like the on you submitted.
    – cap7
    May 6, 2015 at 9:18
  • glad, to help ;) May 6, 2015 at 12:58
1

The definition of your client class should not be tied to how you acquire the data to construct the class. You should review your business requirements of your client class and define it based on that only.

From what you have shown so far, it looks like you need two file processing classes which both are provided a collection of client objects to work on, whether that is for creation or update.

The key thing is that the client class needs to be freestanding from the processing needed for the files. Tomorrow you may need to read from a database, or a web service, or something else, but that certainly doesn't change the definition of a client in your business domain.

4
  • Thank you, that is a good advice. In this case, what can change are the columns of the sources, tomorrow they can add a new field or remove one, and if that happens I must also change the client and adapt to it.
    – cap7
    May 5, 2015 at 16:58
  • If your client class is changing that frequently, you may really need to revisit your business design. Core class definitions(client sounds like one) should not be that dynamic. It's not just that class that would need changing, but every other class/process that deals with it.
    – cdkMoose
    May 5, 2015 at 17:03
  • I might explain my self wrong. Usually I just adapt the file reading methods. Let's I read data from credit reports, the client class is always the same, and will always generate the required outputs.
    – cap7
    May 5, 2015 at 17:06
  • Understood. Just saying that frequent changes to the definition of core classes should be a red flag. Maybe your business needs are changing that frequently, but you should definitely review the big picture if that is happening. As much as possible you want to limit those feed changes to just the file processing, not the core class.
    – cdkMoose
    May 5, 2015 at 17:08
1

If I understand your question, the Facade Pattern fits your needs:

Intent:

  • Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
  • Wrap a complicated subsystem with a simpler interface.

Your Facade, the ClientReport class, has classes SourceA and SourceB by composition. The simpler, unified interface provided by ClientReport delegates to the appropriate methods of SourceA and SourceB; however, the client deals only with the ClientReport interface.

The link above has this checklist for using the Facade pattern:

  1. Identify a simpler, unified interface for the subsystem or component.
  2. Design a 'wrapper' class that encapsulates the subsystem.
  3. The facade/wrapper captures the complexity and collaborations of the component, and delegates to the appropriate methods.
  4. The client uses (is coupled to) the Facade only.
  5. Consider whether additional Facades would add value.
1
  • Yes, you understood correctly.
    – cap7
    May 6, 2015 at 7:45

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