Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've just been reading through the SOLID principles, and this is one I have real difficulty with when designing software. I am relatively new (4 months professionally) at coding.

The idea is simply to encapsulate classes into ones that perform a single task.

For example, what if you have a class that creates and populates a Treeview and configures it to your specification. You then want data retrieved from a database when the user clicks on the nodes. Would you say this is two separate concerns?

  1. Populate and configure the treeview
  2. Obtain data from the database?

Also, in the same app. You have a datagridview that is also populated with dynamic data. Would you therefore put that data retrieval in the same class as the treeview data retrieval or would that be yet another completely seperate class?

Thanks.

share|improve this question
2  
I recommend you also apply your TDD to aid you in design. TDDing your treeview for example would help you see that the data access is a separate concern. –  Martijn Verburg Jan 21 '11 at 9:05
    
+1 for a good question –  Gary Rowe Jan 21 '11 at 10:07
add comment

5 Answers

up vote 7 down vote accepted

Separation of concerns

Each object does its own job. Thus in your example the tree view knows only about being a tree view (presumably displaying data). It may may load its own data but it should not know where the data is coming from. If it knows were the data is coming from then it is tightly coupled with the data source (i.e. It may be a DB now, but what happens in version 2 when you need to get data from the space shuttle?).

Instead you should pass the tree view an interface (that it knows how to use) to retrieve its data from:

// Example
class DataRetrieveInterface
{
     // STUFF
     virtual std::string getItemAt(int index)  = 0;
};
class DBDataRetriever:      public DataRetrieveInterface {};
class ShuttleDataRetriever: public DataRetrieveInterface {};
class MockDataRetriever:    public DataRetrieveInterface { /* Needed for testing */ }

class TreeView
{
    public:
        TreeView(DataRetrieveInterface& data)
        {
             // use data to populate the view.
        }
};

If you re-use the DataRetrieveInterface for the grid is something you need to decide as part of your design. Is generic enough? Alternatively you can derive from this interface and have something more grid-specific for the grid object. At this point there is not enough information in the question to say if you should or should not have a different interface for the grid.

share|improve this answer
3  
+1 for he space shuttle, love it! –  Martijn Verburg Jan 21 '11 at 9:04
    
+1 for a solid answer. And the space shuttle, obviously. –  Gary Rowe Jan 21 '11 at 10:15
add comment

Separate Serialization/Deserialization from classes

I've found personally that it's preferable to separate serialization/deserialization from the actual classes. If you have an class which given data in some format (xml/dataset/json or what you prefer) builds/loads the class. The class should have no dependencies relating to serialization.

That way you can more easily change serialization methods , support different kinds of data and so forth

share|improve this answer
    
+1 for decoupling serialization/deserialization - and marshalling/unmarshalling. In Java this is achieved through annotations and an external builder (JAXBContext). –  Gary Rowe Jan 21 '11 at 10:14
add comment

Rendering data, and retrieving data, are two separate concerns, and so belong in separate objects.

You might have a situation where it makes sense to have a single data retrieval class feeding data to a tree view and a data grid: two different views on the same data. Off-hand it seems unlikely: trees and tables aren't terribly similar.

share|improve this answer
add comment

Think about how you would write a unit-test for that class.

What separate functionality can and would you test? Populating data, configuring, load from database are separate concerns. Splitting them up make them easier to understand, test and reuse.

share|improve this answer
add comment

Possibly you'll find it easier to think of it less as a theory thing and more as a practical thing.

Imagine that you're writing two apps which will provide identical functionality but through two completely different front ends - one web client, one native desktop client (assume both are being written in the same language).

Now, design and code that in such a way that you have as little duplication as is practically possible.

In terms of separating out data retrieval (actually getting the data) and business logic (applying processing and logic to that data), do the same but now assuming that you will have to implement the same solution for both SQL Server and data storage using XML flat files.

Again, design and code in such a way that you have as little duplication as is practically possible.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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