VB.NET, VS 2010, .NET 4
Hello,
I've written an application. I've discovered that it is full of circular references. I would like to rewrite portions of my code to improve its design. I have read about tiered programming and want to implement something like it for my application.
Background: My application is a control program for an industrial machine. It parses a recipe (from an Excel file) which contains timing information and setpoints for the various attached devices. There are three main types of devices: Most are connected through Beckhoff terminals and communicate via TwinCAT (Beckhoff's pseudo-PLC software) and two are RS-232 devices, each with a different communication protocol. I can communicate with the Beckhoff devices via a .NET API provided by Beckhoff. I have written parser classes for the two RS-232 devices. Some of the Beckhoff devices are inputs, some are outputs; some are digital, some are (pseudo-)analog.
I think my problem is that I was trying to wrap my head around OOP while writing the application so I created classes willy-nilly without a clear idea of their hierarchy. At some points, I tried to do what I thought was right by, say, making a "Device" class which was inherited by, say, a "TwinCatDevice" class and a "Rs232Device" class. But then I just stuffed all of the communication code in those classes.
What I'm trying now is creating some communication modules (e.g., UtilTwinCat, UtilRs232) that contain abstract methods like "Connect", "Disconnect", "Read", "Write", etc. Then I'm trying to rewrite my "Device" class and subclasses to use these modules so they don't have to contain any of the (sometimes redundant) communication code.
Here's my question: Would it be good design to create separate classes for each type of communication type? i.e., should I have, say, "TwinCatReadOnlyDigital", "TwinCatReadOnlyAnalog", "TwinCatWriteOnlyDigital", "TwinCatWriteOnlyAnalog", "TwinCatReadWriteDigital", "TwinCatReadWriteAnalog", "Rs232ReadOnlyDigital", etc? Or perhaps some interfaces like IReadOnly, IWriteOnly, IDuplex?
This seems like it can't be the right approach in that I imagine someone who is good at programming wouldn't end up with a billion different classes for every eventuality. Is there some way I could selectively implement an interface on a class at run time? I think that's a stupid question... I'm still trying to wrap my head around why one would use an interface. I'm looking for some basic insight on how to grapple with this type of design problem. Specifically, if you have a lot of "things" that differ slightly, is the best approach to create lots of classes that differ slightly?
Thanks a lot in advance,
Brian
Edit: I just wanted to add, to be clear, there is a finite number of devices whose parameters are known, so it would be straightforward to write classes for all the types I'd need. I just wonder if there's a better approach.
That's not really enough information for any concrete answers, but let me make a few suggestions.
"I'm still trying to wrap my head around why one would use an interface."
Mainly because then you can "program to the interface", that is you needn't care if you're working with a Beckhoff or an RS-232 device - you only care that you can send data to it. Just to make it clear: interfaces don't contain implementations. Classes implementing an interface promise to provide concrete implementations for the functions of the interface.
Instead of IReadOnly, IWriteOnly and IDuplex use two interfaces: IWriteable and IReadable (or whatever names make sense). Duplex classes will implement both interfaces.
The Strategy or more likely the Template method patterns may help you with the slightly different classes. Maybe even simple subclassing, but keep in mind that there's often a simpler, nicer solution.
Don't repeat yourself (DRY): try to find one and only one place for every piece of logic.
Functionality shared by several classes should reside in a superclass or utility classes.
Also, more concrete questions will result in more concrete answers :)
Related
I have a Component which has API exposed with some 10 functionality in all. I can think of two ways to achieve it:
Give out all these functionality as separate functions.
Expose only one function which takes an XML as input. Based on request_Type specified and the parameters passed in the XML, I internally call one of the respective functions.
Q1. Will the second design be more loosely coupled than the first ?
I always read about how I should try my components to be loosely coupled, should I really go to this extent to achieve lose coupling ?
Q2. Which one of these would be a better design in terms of OOP and why?
Edit:
If I am exposing this API over D-Bus for others to use, will type checking still be a consideration to compare the two approaches? From what I understand type checking is done at compile time, but in case when this function is exposed over some IPC, issue of type checking comes into picture ?
The two alternatives you propose do not differ in the (obviously quite large) number of "functions" you want to offer from your API. However, the second seems to have many disadvantages because you are loosing any strong type checking, it will become much harder to document the functionality etc. (The only advantage I see is that you don't need to change your API if you add functionality. But at the disadvantage that users will not be able to figure out API changes like deleted functions until run-time.)
What is more related with this question is the Single Responsiblity Principle (http://en.wikipedia.org/wiki/Single_responsibility_principle). As you are talking about OOP, you should not expose your tens of functions within one class but split them among different classes, each with a single responsibility. Defining good "responsibilities" and roles requires some practice, but following some basic guidelines will help you to get started quickly. See Are there any rules for OOP? for a good starting point.
Reply to the question edit
I haven't used D-Bus, so this might be totally wrong. But from a quick look at the tutorial I read
Each object supports one or more interfaces. Think of an interface as
a named group of methods and signals, just as it is in GLib or Qt or
Java. Interfaces define the type of an object instance.
DBus identifies interfaces with a simple namespaced string, something
like org.freedesktop.Introspectable. Most bindings will map these
interface names directly to the appropriate programming language
construct, for example to Java interfaces or C++ pure virtual classes.
As far as I understand, D-Bus has the concept of differnt objects which provide interfaces consisting of several methods. This means (to me) that my answer above still applies. The "D-Bus native" way of specifying your API would mean to exhibit interfaces and I don't see any reason why good OOP design guidelines shouldn't be valid, here. As D-Bus seems to map these even to native language constructs, this is even more likely.
Of course, nobody keeps you from just building your own API description language in XML. However, things like are some kind of abuse of underlying techniques. You should have good reasons for doing such things.
I've been working on a small project using C++ (although this question might be considered language-agnostic) and I'm trying to write my program so that it is as efficient and encapsulated as possible. I'm a self-taught and inexperienced programmer but I'm trying to teach myself good habits when it comes to using interfaces and OOP practices. I'm mainly interested in the typical 'best' practices when it comes to accessing the methods of an object that is acting as a subsystem for another class.
First, let me explain what I mean:
An instance of ClassGame wants to render out a 2d sprite image using the private ClassRenderer subsystem of ClassEngine. ClassGame only has access to the interface of ClassEngine, and ClassRenderer is supposed to be a subsystem of ClassEngine (behind a layer of abstraction).
My question is based on the way that the ClassGame object can indirectly make use of ClassRenderer's functionality while still remaining fast and behind a layer of abstraction. From what I've seen in lessons and other people's code examples, there seems to be two basic ways of doing this:
The first method that I learned via a series of online lectures on OOP design was to have one class delegate tasks to it's private member objects internally. [ In this example, ClassGame would call a method that belongs to ClassEngine, and ClassEngine would 'secretly' pass that request on to it's ClassRenderer subsystem by calling one of its methods. ] Kind of a 'daisy chain' of function calls. This makes sense to me, but it seems like it may be slower than some alternative options.
Another way that I've seen in other people's code is have an accessor method that returns a reference or pointer to the location of a particular subsystem. [ So, ClassGame would call a simple method in ClassEngine that would return a reference/pointer to the object that makes up its ClassRenderer subsystem ]. This route seems convenient to me, but it also seems to eliminate the point of having a private member act as a sub-component of a bigger class. Of course, this also means writing much fewer 'mindless' functions that simply pass a particular task on, due to the fact that you can simply write one getter function for each independent subsystem.
Considering the various important aspects of OO design (abstraction, encapsulation, modularity, usability, extensibility, etc.) while also considering speed and performance, is it better to use the first or the second type of method for delegating tasks to a sub-component?
The book Design Patterns Explained discusses a very similar problem in its chapter about the Bridge Pattern. Apparently this chapter is freely available online.
I would recommend you to read it :)
I think your type-1 approach resembles the OOP bridge pattern the most.
Type-2, returning handles to internal data is something that should generally be avoided.
There are many ways to do what you want, and it really depends on the context (for example, how big the project is, how much you expect to reuse from it in other projects etc.)
You have three classes: Game, Engine and Renderer. Both of your solutions make the Game commit to the Engine's interface. The second solution also makes the Game commit to the Renderer's interface. Clearly, the more interfaces you use, the more you have to change if the interfaces change.
How about a third option: The Game knows what it needs in terms of rendering, so you can create an abstract class that describes those requirements. That would be the only interface that the Game commits to. Let's call this interface AbstractGameRenderer.
To tie this into the rest of the system, again there are many ways. One option would be:
1. Implement this abstract interface using your existing Renderer class. So we have a class GameRenderer that uses Renderer and implements the AbstractGameRenderer interface.
2. The Engine creates both the Game object and the GameRenderer object.
3. The Engine passes the GameRenderer object to the Game object (using a pointer to AbstractGameRenderer).
The result: The Game can use a renderer that does what it wants. It doesn't know where it comes from, how it renders, who owns it - nothing. The GameRenderer is a specific implementation, but other implementations (using other renderers) could be written later. The Engine "knows everything" (but that may be acceptable).
Later, you want to take your Game's logic and use it as a mini-game in another game. All you need to do is create the appropriate GameRenderer (implementing AbstractGameRenderer) and pass it to the Game object. The Game object does not care that it's a different game, a different Engine and a different Renderer - it doesn't even know.
The point is that there are many solutions to design problems. This suggestion may not be appropriate or acceptable, or maybe it's exactly what you need. The principles I try to follow are:
1. Try not to commit to interfaces you can't control (you'll have to change if they change)
2. Try to prevent now the pain that will come later
In my example, the assumption is that it's less painful to change GameRenderer if Renderer changes, than it is to change a large component such as Game. But it's better to stick to principles (and minimise pain) rather than follow patterns blindly.
I have a very limited understanding of OOP.
I've been programming in .Net for a year or so, but I'm completely self taught so some of the uses of the finer points of OOP are lost on me.
Encapsulation, inheritance, abstraction, etc. I know what they mean (superficially), but what are their uses?
I've only ever used OOP for putting reusable code into methods, but I know I am missing out on a lot of functionality.
Even classes -- I've only made an actual class two or three times. Rather, I typically just include all of my methods with the MainForm.
OOP is way too involved to explain in a StackOverflow answer, but the main thrust is as follows:
Procedural programming is about writing code that performs actions on data. Object-oriented programming is about creating data that performs actions on itself.
In procedural programming, you have functions and you have data. The data is structured but passive and you write functions that perform actions on the data and resources.
In object-oriented programming, data and resources are represented by objects that have properties and methods. Here, the data is no longer passive: method is a means of instructing the data or resource to perform some action on itself.
The reason that this distinction matters is that in procedural programming, any data can be inspected or modified in any arbitrary way by any part of the program. You have to watch out for unexpected interactions between different functions that touch the same data, and you have to modify a whole lot of code if you choose to change how the data is stored or organized.
But in object-oriented programming, when encapsulation is used properly, no code except that inside the object needs to know (and thus won't become dependent on) how the data object stores its properties or mutates itself. This helps greatly to modularize your code because each object now has a well-defined interface, and so long as it continues to support that interface and other objects and free functions use it through that interface, the internal workings can be modified without risk.
Additionally, the concepts of objects, along with the use of inheritance and composition, allow you to model your data structurally in your code. If you need to have data that represents an employee, you create an Employee class. If you need to work with a printer resource, you create a Printer class. If you need to draw pushbuttons on a dialog, you create a Button class. This way, not only do you achieve greater modularization, but your modules reflect a useful model of whatever real-world things your program is supposed to be working with.
You can try this: http://homepage.mac.com/s_lott/books/oodesign.html It might help you see how to design objects.
You must go though this I can't create a clear picture of implementing OOP concepts, though I understand most of the OOP concepts. Why?
I had same scenario and I too is a self taught. I followed those steps and now I started getting a knowledge of implementation of OOP. I make my code in a more modular way better structured.
OOP can be used to model things in the real world that your application deals with. For example, a video game will probably have classes for the player, the badguys, NPCs, weapons, ammo, etc... anything that the system wants to deal with as a distinct entity.
Some links I just found that are intros to OOD:
http://accu.informika.ru/acornsig/public/articles/ood_intro.html
http://www.fincher.org/tips/General/SoftwareEngineering/ObjectOrientedDesign.shtml
http://www.softwaredesign.com/objects.html
Keeping it very brief: instead of doing operations on data a bunch of different places, you ask the object to do its thing, without caring how it does it.
Polymorphism: different objects can do different things but give them the same name, so that you can just ask any object (of a particular supertype) to do its thing by asking any object of that type to do that named operation.
I learned OOP using Turbo Pascal and found it immediately useful when I tried to model physical objects. Typical examples include a Circle object with fields for location and radius and methods for drawing, checking if a point is inside or outside, and other actions. I guess, you start thinking of classes as objects, and methods as verbs and actions. Procedural programming is like writing a script. It is often linear and it follows step by step what needs to be done. In OOP world you build an available repetoire of actions and tasks (like lego pieces), and use them to do what you want to do.
Inheritance is used common code should/can be used on multiple objects. You can easily go the other way and create way too many classes for what you need. If I am dealing with shapes do I really need two different classes for rectangles and squares, or can I use a common class with different values (fields).
Mastery comes with experience and practice. Once you start scratching your head on how to solve particular problems (especially when it comes to making your code usable again in the future), slowly you will gain the confidence to start including more and more OOP features into your code.
Good luck.
When do you encourage programming against an interface and not directly to a concrete class?
A guideline that I follow is to create abstractions whenever code requires to cross a logical/physical boundary, most especially when infrastructure-related concerns are involved.
Another checkpoint would be if a dependency will likely change in the future, due to possible additional concerns code (such as caching, transactional awareness, invoking a webservice instead of in-process execution) or if such dependencies have direct references to infrastructure integration points.
If code depends on something that does not require control to cross a logical/physical boundary, I more or less don't create abstractions to interact with those.
Am I missing anything?
Also, use interfaces when
Multiple objects will need to be acted upon in a particular fashion, but are not fundamentally related. Perhaps many of your business objects access a particular utility object, and when they do they need to give a reference of themselves to that utility object so the utility object can call a particular method. Have that method in an interface and pass that interface to that utility object.
Passing around interfaces as parameters can be very helpful in unit testing. Even if you have just one type of object that sports a particular interface, and hence don't really need a defined interface, you might define/implement an interface solely to "fake" that object in unit tests.
related to the first 2 bullets, check out the Observer pattern and the Dependency Injection. I'm not saying to implement these patterns, but they illustrate types of places where interfaces are really helpful.
Another twist on this is for implementing a couple of the SOLID Principals, Open Closed principal and the Interface Segregation principle. Like the previous bullet, don't get stressed about strictly implementing these principals everywhere (right away at least), but use these concepts to help move your thinking away from just what objects go where to thinking more about contracts and dependency
In the end, let's not make it too complicated: we're in a strongly typed world in .NET. If you need to call a method or set a property but the object you're passing/using could be fundamentally different, use an interface.
I would add that if your code is not going to be referenced by another library (for a while at least), then the decision of whether to use an interface in a particular situation is one that you can responsibly put off. The "extract interface" refactoring is easy to do these days. In my current project, I've got an object being passed around that I'm thinking maybe I should switch to an interface; I'm not stressing about it.
Interfaces abstraction are convenient when doing unit test. It helps for mocking test objects. It very useful in TDD for developing without actually using data from your database.
If you don't need any features of the class that aren't found in the Interface...then why not always prefer the Interface implementation?
It will make your code easier to modify in the future and easier to test (mocking).
you have the right idea, already. i would only add a couple of notes to this...
first, abstraction does not mean 'interface'. for example, a "connection string" is an abstraction, even though it's just a string... it's not about the 'type' of the thing in question, it's about the intention of use for that thing.
and secondly, if you are doing test automation of any kind, look for the pain and friction that are exposed by writing the tests. if you find yourself having to set up too many external conditions for a test, it's a sign that you need a better abstraction between the thing your testing and the things it interacts with.
I think you've said it pretty well. Much of this will be a stylistic thing. There are open source projects I've looked at where everything has an interface and an implementation, and it's kind of frustrating, but it might make iterative development a little easier, since any objects implementation can break but dummies will still work. But honestly, I can dummy any class that doesn't overuse the final keyword by inheritance.
I would add to your list this: anything which can be thought of as a black box should be abstracted. This includes some of the things you've mentioned, but it also includes hairy algorithms, which are likely to have multiple useful implementations with different advantages for different situation.
Additionally, interfaces come in handy very often with composite objects. That's the only way something like java's swing library gets anything done, but it can also be useful for more mundane objects. (I personally like having an interface like ValidityChecker with ways to and-compose or or-compose subordinate ValidityCheckers.)
Most of the useful things that come with the Interface passing have been already said. However I would add:
implementing an interface to an object, or later multiple objects, FORCES all the implementers to follow an IDENTICAL pattern to implement contract with the object. This can be useful in case you have not so OOP-experienced-programmers actually writing the implementation code.
in some languages you can add attributes on the interface itself, which can be different from the actual object implementation attribute as sense and intent
From what I have read best practice is to have classes based on an interface and loosely couple the objects, in order to help code re-use and unit test.
Is this correct and is it a rule that should always be followed?
The reason I ask is I have recently worked on a system with 100’s of very different objects. A few shared common interfaces but most do not and wonder if it should have had an interface mirroring every property and function in those classes?
I am using C# and dot net 2.0 however I believe this question would fit many languages.
It's useful for objects which really provide a service - authentication, storage etc. For simple types which don't have any further dependencies, and where there are never going to be any alternative implementations, I think it's okay to use the concrete types.
If you go overboard with this kind of thing, you end up spending a lot of time mocking/stubbing everything in the world - which can often end up creating brittle tests.
Not really. Service components (class that do things for your application) are a good fit for interfaces, but as a rule I wouldn't bother having interfaces for, say, basic entity classes.
For example:
If you're working on a domain model, then that model shouldn't be interfaces. However if that domain model wants to call service classes (like data access, operating system functions etc) then you should be looking at interfaces for those components. This reduces coupling between the classes and means it's the interface, or "contract" that is coupled.
In this situation you then start to find it much easier to write unit tests (because you can have stubs/mocks/fakes for database access etc) and can use IoC to swap components without recompiling your applications.
I'd only use interfaces where that level of abstraction was required - i.e. you need to use polymorphic behaviour. Common examples would be dependency injection or where you have a factory-type scenario going on somewhere, or you need to establish a "multiple inheritance" type behaviour.
In my case, with my development style, this is quite often (I favour aggregation over deep inheritance hierarchies for most things other than UI controls), but I have seen perfectly fine apps that use very little. It all depends...
Oh yes, and if you do go heavily into interfaces - beware web services. If you need to expose your object methods via a web service they can't really return or take interface types, only concrete types (unless you are going to hand-write all your own serialization/deserialization). Yes, that has bitten me big time...
A downside to interface is that they can't be versioned. Once you shipped the interface you won't be making changes to it. If you use abstract classes then you can easily extend the contract over time by adding new methods and flagging them as virtual.
As an example, all stream objects in .NET derive from System.IO.Stream which is an abstract class. This makes it easy for Microsoft to add new features. In version 2 of the frameworkj they added the ReadTimeout and WriteTimeout properties without breaking any code. If they used an interface(say IStream) then they wouldn't have been able to do this. Instead they'd have had to create a new interface to define the timeout methods and we'd have to write code to conditionally cast to this interface if we wanted to use the functionality.
Interfaces should be used when you want to clearly define the interaction between two different sections of your software. Especially when it is possible that you want to rip out either end of the connection and replace it with something else.
For example in my CAM application I have a CuttingPath connected to a Collection of Points. It makes no sense to have a IPointList interface as CuttingPaths are always going to be comprised of Points in my application.
However I uses the interface IMotionController to communicate with the machine because we support many different types of cutting machine each with their own commend set and method of communications. So in that case it makes sense to put it behind a interface as one installation may be using a different machine than another.
Our applications has been maintain since the mid 80s and went to a object oriented design in late 90s. I have found that what could change greatly exceeded what I originally thought and the use of interfaces has grown. For example it used to be that our DrawingPath was comprised of points. But now it is comprised of entities (splines, arcs, ec) So it is pointed to a EntityList that is a collection of Object implementing IEntity interface.
But that change was propelled by the realization that a DrawingPath could be drawn using many different methods. Once that it was realized that a variety of drawing methods was needed then the need for a interface as opposed to a fixed relationship to a Entity Object was indicated.
Note that in our system DrawingPaths are rendered down to a low level cutting path which are always series of point segments.
I tried to take the advice of 'code to an interface' literally on a recent project. The end result was essentially duplication of the public interface (small i) of each class precisely once in an Interface (big I) implementation. This is pretty pointless in practice.
A better strategy I feel is to confine your interface implementations to verbs:
Print()
Draw()
Save()
Serialize()
Update()
...etc etc. This means that classes whose primary role is to store data - and if your code is well-designed they would usually only do that - don't want or need interface implementations. Anywhere you might want runtime-configurable behaviour, for example a variety of different graph styles representing the same data.
It's better still when the thing asking for the work really doesn't want to know how the work is done. This means you can give it a macguffin that it can simply trust will do whatever its public interface says it does, and let the component in question simply choose when to do the work.
I agree with kpollock. Interfaces are used to get a common ground for objects. The fact that they can be used in IOC containers and other purposes is an added feature.
Let's say you have several types of customer classes that vary slightly but have common properties. In this case it is great to have a ICustomer interface to bound them together, logicaly. By doing that you could create a CustomerHander class/method that handels ICustomer objects the same way instead of creating a handerl method for each variation of customers.
This is the strength of interfaces.
If you only have a single class that implements an interface, then the interface isn't to much help, it just sits there and does nothing.