views:

82

answers:

4

I'm having some trouble deciding how two classes should interact and the problem I'm having seems like it would come up a lot so I was wondering if anyone knows of a design pattern (or any kind of solution) that addresses my issue.

Basically I have two classes. Class A deals with displaying information to the user and Class B deals with storing data. Class A needs to get data from class B, format the data based on Class A's internal state, and output the data. For example Class B contains English strings and Class A will always translate those strings into a language that is specified by an instance variable of Class A before preforming any further processing on them.

I can come up with two potential solutions for this but neither of them seem very clean.

  1. Make Class B an instance variable of Class A. Write function in Class A that get the data out of Class B and format it for use in other functions in Class A. This solution doesn't seem great because it does not stop Class A from directly accessing the data in Class B without formatting it.

  2. Make a Class C that extends Class B. Make Class C an instance variable of Class A. Class C will override the Getters of Class B so that the formatting is always applied to the data. However in order to format the data Class C needs to know about Class A's internal state. This could be accomplished by passing a pointer to Class A into the constructor of Class C. Class C could then call a function in Class A that calculated Class A's internal state.

Let me know if this is confusing and I could provide a more concrete example.

thanks

A: 

Sounds like either:

Skilldrick
It is not either-or: the latter is the application of the former to GUIs.
Péter Török
@Péter, Not all GUI frameworks use the Observer pattern to bind models and views.
Huperniketes
@Huperniketes, my understanding so far has been that Model-View(-Controller) includes Observer (possibly under a different name, such as Publisher-Subscriber). Do you have an example of the contrary?
Péter Török
@Péter, the MVC model used in Apple's Cocoa framework originally used, and still does, Controllers which directly coordinated Model and View. At has since added the ability to bind them using an Observer.
Huperniketes
+1  A: 

I'm not sure its as pure as a "design pattern" choice and possibly more of a design principle. For example,

Single Responsibility - a class should do one thing, and ONLY 1 thing.

Have a look at SOLID.

http://en.wikipedia.org/wiki/Solid_(object-oriented_design)

It sounds like you might want Class B (your dataprovider) to be implementing an Interface, and you'll have several flavours of data provider classes (variants that all implement this interface). If you referenced any dataprovider from Class A, you'd use the interface, not the specific implementation (class-type). That way you can swap different data providers in and out without ever having to modify Class A as well...

Neil Fenwick
I like this idea but it doesn't address how some of the implementations of B will get at the internal state of Class A.
rob
Glad you liked the idea. B probably shouldn't be coupled with A either. Depending on what you want to do, possibly introduce another class for that task. e.g. like the .NET StringConverter does for the framework
Neil Fenwick
+3  A: 

In alternative #1, I don't think "stopping Class A from directly accessing the data in Class B without formatting it" is a concern. Any class can fail to do what it says it does, it doesn't take a bad design to do that. So I don't think that's a valid concern. A is the only thing that knows its internal state, so it should be providing the logic to transform the output.

One alternative to that, which may be overengineered for your needs, is to use something like the Strategy pattern. Basically, B accepts a strategy to format data, and in that function (that A would provide) you could rely on A's state.

Something like this:

interface FormattingStrategy {
    public String format(String input);
}

class B {
    public String getFormattedStringA(FormattingStrategy formatter)...
}

class A {

    public void someMethod() {
         String a = getFormattedStringA(new FormattingStrategy() {
             public String format(String input) {
                 if (someAState) {
                    //...
                 }
             }
         };
    }
}

The strategy could be an instance variable of A. This keeps B completely decoupled from A, only coupled to the FormattingStrategy interface.

Mark Peters
I think this strategy pattern will work but me but I can't find a good way to declare the instance of FormattingStrategy. My application is in C++ so if I make the instance of FormattingStrategy a nested class in Class A then it won't have access to Class A's member variables and functions (At least I think this is how nested classes work in C++). Any suggestions?
rob
Sorry @rob, it's been a long time since I've done anything in C++. The question was language agnostic so I just gave an example in Java. With C++ you can leverege friend classes though; the implementation of FormattingStrategy could accept an instance of A and be declared a friend of A.
Mark Peters
A: 

Hi,
one mistake you make is the naming of classes A, B, C you should not do this. Better is to name your classes like more real objects e.g like a occupation or real things, because you will get the solution right out of the names. If you mention patterns...
they have names like: Model-View, Fabrique, Decorator, Observer. dig it?
to your problem: the class with data is your "model" the class that shows your data is your "view"
If you deal with languages maybe have a look at the interpreter pattern. But I must confess I do not really understand the problem, it sounds a kind of confused to me

Oops