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.

My time as a developer (~8 yrs) has been spent creating tooling/automation of one sort or another. The tools I develop usually interface with one or more API's. These API's could be win32, WMI, VMWare, a help-desk application, LDAP, you get the picture. The apps I develop could be just to pull back data and store/report. It could be to provision groups of VM's to create live like mock environments, update a trouble ticket etc.

I've been developing in .Net and I'm currently reading into design patterns and trying to think about how I can improve my skills to make better use of and increase my understanding of OOP. For example, I've never used an interface of my own making in anger (which is probably not a good thing), because I honestly cannot identify where using one would benefit later on when modifying my code. My classes are usually very specific and I don't create similar classes with similar properties/methods which could use a common interface (like perhaps a car dealership or shop application might).

I generally use an n-tier approach to my apps, having a presentation layer, a business logic/manager layer which interfaces with layer(s) that make calls to the API's I'm working with. My business entities are always just method-less container objects, which I populate with data and pass back and forth between my API interfacing layer using static methods to proxy/validate between the front and the back end.

My code by nature of my work, has few common components, at least from what I can see. So I'm struggling to see how I can better make use of OOP design and perhaps reusable patterns.

Am I right to be concerned that I could be being smarter about how I work, or is what I'm doing now right for my line of work? Or, am I missing something fundamental in OOP?

EDIT: Here is some basic code to show how my mgr and api facing layers work. I use static classes as they do not persist any data, only facilitate moving it between layers.

public static class MgrClass
{
    public static bool PowerOnVM(string VMName)
    {
        // Perform logic to validate or apply biz logic
        // call APIClass to do the work
        return APIClass.PowerOnVM(VMName);
    }
}

public static class APIClass
{
    public static bool PowerOnVM(string VMName)
    {
        // Calls to 3rd party API to power on a virtual machine
        // returns true or false if was successful for example
    }
}
share|improve this question

migrated from stackoverflow.com Apr 4 '12 at 20:02

This question came from our site for professional and enthusiast programmers.

    
Interesting question.. not sure there is a valid answer to this? Can you post some sample code where you feel you may be missing out on OOP principles? –  KP. Apr 4 '12 at 19:23
    
OOP gives you more power and flexibility. If you are creating complex objects and they have relationships ( x Is a y, x has a y) and both of those objects are complex, then OOP simplifies that and make it easier to work with. You do not always need to use OOP. –  D3mon-1stVFW Apr 4 '12 at 19:23
    
This question is a bad fit for StackOverflow; try to ask questions here that directly pertain to specific coding problems, and that are of general usefulness to a broad audience. Your question is not about a specific coding problem and pertains only to you. –  Eric Lippert Apr 4 '12 at 19:57
    
KP01, I have added some example code. Thanks –  Tom Pickles Apr 4 '12 at 20:37
    
possible duplicate of Is it bad habit not using interfaces? –  gnat May 21 '13 at 15:52

4 Answers 4

up vote 2 down vote accepted

Sounds like you might be missing a lot. Development patterns have been around for a long time and they really help with OOP. I would suggest reading about these patterns.

For a start have a look at SOLID - http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) There are 5 basic development patterns.

With regards to interfaces, they are really usefull. Interface defines the methods available and the concrete class provides the implementation. If you use interfaces you can easily swap classes to provide different functionality (without having to change the rest of the application). An example of that would be data access layer. Imagine if you develope your application which uses LINQ to SQL. Some time later the requirement is to change the data provider to something else. Now, if that was running of an interface with properly implemented Command Pattern http://en.wikipedia.org/wiki/Command_pattern , this would be very easy. You would only have to create new data access layer, implement the interface and that's it.

It's worth reading about the design patterns and all features given by OOP.

Hope that helps.

UPDATE

Based on your example, your APIClass already follows single responsibility pattern.

The way you could implement interface would be :

public interface IVMManager
{
    bool PowerOnVM(string VMName);
    bool PowerOffVM(string VMName);
}

public class MgrClass 
{ 
    private IVMManager _vmManager;

    public MgrClass(IVMManager vmManager)
    {
        _vmManager = vmManager;
    }

    public bool PowerOnVM(string VMName) 
    { 
        // Perform logic to validate or apply biz logic 
        // call APIClass to do the work 
        return _vmManager.PowerOnVM(VMName); 
    } 
} 

public class APIClass : IVMManager
{    
    public bool PowerOnVM(string VMName)    
    {
        //IMPLEMENTATION
    }    
}    

REMEMBER : static methods cannot be exposed via interface !

This example also follows the command pattern. VM Manager is easily swapable with different implementation. You can also unit test this class.

Hope that gives you an idea how design patterns can be used and how powerfull OOP is.

share|improve this answer
    
Hi Sebastian. I'm currently reading into design patterns, but struggling to work out how to utilise them in my own work. –  Tom Pickles Apr 4 '12 at 20:39
1  
@Erik Dietrich I've just updated my answer to give you an example. –  Sebastian Siek Apr 4 '12 at 20:52
    
Thank you very much. I have spent some time rewriting an app I am working on now with your code pattern. It took me a while to understand the pattern as it's not as I do it now, but now it makes sense and I'm grateful for your assistance. –  Tom Pickles Apr 5 '12 at 16:58

I'd recommend you take a look at SOLID (here's a link) and from those start with interface segregation, dependency injection principle and single responsibility principle. They are all good, but I can immediately see that IS and DI could help you.

Next take a look at unit testing and test driven development. When you look at TDD (Test Driven Development) remember there is also TAD (After instead of driven). That just means you code as you always have and write tests afterwards. You lose the benefits of TDD, but it still helps you start to think in terms of outcomes and units.

When you are looking at testing you'll start seeing reference to mocking. Mocking means taking a bit of code you want to test that is dependent on bits of code you don't want to test and mocking out (replacing with a functional fake) the bits you don't want to test.

There are then loads of patterns which are useful, and you almost certainly already use a lot of them. Take a look at strategy pattern. That's a nice one.

Finally look at anti patterns. It might just be interesting to get the idea that just as there are commonly accepted good patterns of code reuse, there are also bad ones that you shouldn't fall into.

That isn't suppose to be an all in tutorial, but it will nudge you into the right direction to start seeing the benefits on your own I think.

share|improve this answer

If you're never using interfaces and are using a layered approach, it seems fairly likely that you could be missing an opportunity for some decoupling and/or reuse, but it's really impossible to say without seeing the code.

One thing I might consider is asking whether or not you write automated tests (unit tests). Interfaces are often quite helpful with this and tend to emerge sort of naturally as you look for ways to isolate testable units. If you're not unit testing, you're missing not only a potential part of OOP, but a fundamental part of writing good reliable software. So, if you're not doing that, I'd suggest giving it a try, and seeing if some interface use (and perhaps even design pattern use) don't emerge 'organically' as you do it.

share|improve this answer
    
Hi Erik, I've added some basic code as an example. If you need more I can provide. I do not write unit tests for my code. I usually work with a dev implementation of the API provider. Thanks. –  Tom Pickles Apr 4 '12 at 20:35

The key point of OOP that often gets lost in the acronym/pattern/kool-aid confusion is that you're thinking in terms of objects that govern problem domains interacting with each other rather than a pile of methods (or one-method classes with no other properties) that just run data through a series of hoops.

There are really only two things I focus on when thinking about how to write classes/constructors.

Encapsulation

When data is essentially just consumed and reprocessed through 20 method calls in long return/param chain that all live in different places, how different is that from just having a global var that they all act on? Altering the structure of that data still likely means you have to have to alter all 20 methods and debug who-dun-its will still require following a full trace to get to the source of a problem since there's no way to know what corner of an app was touching that data when it broke.

If data lives in one class and it only enters a given system via that class. You only have to validate, package, and canonicalize it once in that one place until you finally move it to some other object as some major step in a process (e.g. db layer to service handling class or service handling class to client).

Now it may seem I'm advocating gigantor classes that do everything under the sun. Not at all. The key thing to having a single-point of entry isn't to have huge classes (although I would say that SOLID has lead to devs thinking overly small classes are more appropriate than they often are in codebases I've worked in). But rather layer up by compositing as needed. Just make that point of entry stuff the responsibility of one higher-level class so whatever gets used inside it through compositing/internal classes doesn't have to.

Writing to an Interface

No, not the thing you tack on to a class definition to assert a contract in C#/Java. I mean the actual set of methods you're exposing as an API. The more you write your classes/objects as having a role to fill by providing a set of useful methods that give just enough granularity without making you re-do any of the pointless detail work, the less you'll be scooting data around and creating inflexibility and needless dependencies. And the less you'll be tempted to put tests and contracts on absolutely everything in your codebase because you've made a mess out of things by creating a needless hornets nest of dependencies.

The key thing is to stop thinking in terms of the series of steps to get from point A to point B to ... and instead think about who needs to be able to do what, establish those classes and methods and then fill in the blanks and get them working with each other.

The Wins You Should Be Getting

  • Easier to Read/Understand/Debug: At some higher level you should see a few objects interacting. And then see greater detail as you work your way down. Through this, it should be easier to narrow down which components of an app are responsible for a problem before you even set your first breakpoint. If you generally always debug by finding the trigger for something and tracing through the entire process without even trying to read the code like a human first, you're probably not employing very good OOD.
  • Easier to Modify: Encapsulating/designing well reduces dependencies. As long as a given class/object's interface does what it's expected to do you need never worry about how other changes you make in the interior will impact the rest of an app.
  • Easier to Reuse: Well-designed classes should make it easy to move large portions of related functionality into other codebases with a minimum of modification.
share|improve this answer

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.