Following on from this thread I started The Singleton PatternIt got me thinking about how coupled my classes are and how best to achieve loose coupling.  Please bear in mind I am a new programmer (4 months into my first job) and this is really the first consideration I have given to this, and am very keen to understand the concept.So, what exactly constitutes loose coupling vs heavy coupling?  In my current(and first project), I am working on a c# winforms project, where the GUI section creates objects and subcribes to their events, when they are triggered, the GUI creates another object (in this example, a datagridview (a class that I have created that wraps around a standard datagridview and adds additional functionality) and attaches it to the GUI.  Is this bad coupling or good?  I really don't want to get into bad habits and start coding poorly, hence I would appreciate your responses.
Coupling. Best practices
language agnostic;coupling
TO make your code loosely coupled here are a few simple things to remember:Part 1:Technically known as Separation of Concern. Each class has a specific role, it should be handling business logic or application logic. Try and steer clear of class that combine both responsibilities. i.e. A class that manages (broad term) data is application logic while a class that uses data is business logic.Personally I refer to this (in my own little world) as create it or use it. A class should create an object or use an object it should never do both.Part 2:How to implement separation of concern.As a starting point there are two simple techniques:Dependency InjectionService Locator PatternNote: Design patterns are not absolute.They are supposed to be customized to the situation but have an underlying theme that is similar to all applications. So don't look at the examples below and say that I must follow this rigidly; these are just examples (and slightly contrived at that).Dependency Injection:This is  where you pass in an object that a class uses. The object that you pass in based on an interface so your class knows what to do with it but does not need to know the actual implementation.class Tokenizer{    public:        Tokenizer(std::istream& s)            : stream(s)        {}        std::string nextToken() { std::string token; stream >> token;return token;}    private:        std::istream& stream;};Here we inject the stream into a Tokenizer. The tokenizer does not know what type the stream is as long as it implements the interface of std::istream.Service Locator Pattern:The service locator pattern is a slight variation on dependency injection. Rather than give an object that it can use, you pass it an object that knows how to locate(create) the object you wants to use.class Application{     public:         Application(Persister& p)             : persistor(p)         {}         void save()         {             std::auto_ptr<SaveDialog> saveDialog = persistor.getSaveDialog();             saveDialog.DoSaveAction();         }         void load()         {             std::auto_ptr<LoadDialog> loadDialog = persistor.getLoadDialog();             loadDialog.DoLoadAction();         }    private:        Persister& persistor;};Here we pass the application object a persistor object. When you perform a save/load action it uses the persistor to create an object that actually knows how to do the action. Note: Again the persistor is an interface and you can provide different implementations depending on the situation. This is useful when a potentially unique object is required each time you instantiate an action.Personally I find this is particularly useful in writing unit tests.Note of Patterns:Design patterns is a huge subject unto itself. This is by no means an exclusive list of patterns you can use to help with loose coupling; this is just a common starting point.  With experience you will realize you are already using these patterns its just that you did not use their formal names. By standardizing their names (and getting everybody to learn them) we find that it is easy and quicker to communicate ideas.