This is tongue in cheek and using a programming language you probably don't know, but it's still informative and a good advice
Principles of OO Design, or Everything I Know About Programming, I Learned from Dilbert
Some background... I don't work in the games industry and will not be making games. I have an electrical engineering background and I do digital design/embedded systems work and am strong in C and comfortable using assembly when needed. With the industry I work in I'd likely be developing in C++ or Java rather than C# or whatever the newest high level language is, but at the same time learning the semantics of a specific language has never been a problem for me. I also have a good background in theoretical computer science (algorithms, etc), I just never implemented in OOP.
I've always been interested in taking on more software projects, but I've never properly learned object oriented programming in a classroom and haven't been very successful at teaching myself. When I see OOP code I can understand it (and can see the elegance of it and understand why it's best for high-level design), but if I were tasked to develop an OOP project from scratch I can't do it because I'm so used to procedural thinking. That said, I'm only 28 so not old enough to use the excuse of I'm stuck in my ways :P. Are there any good books or sites that QT3ers can recommend that teach for this? Also, for those that can do both, are you easily able to switch back and forth between both paradigms?
Thanks!
*************
Some extra information for those interested, most of my tasks now are FPGA designs that include an embedded processor, and I usually do all the Verilog/VHDL and microprocessor C code. I don't want to get into why here, but I believe skills in HDL design specifically are going to become less appreciated/valued in the future, so this is driving me even more to want to improve my traditional software engineering skills. Another path I could take would be to improve some of my old EE knowledge (RF design, PCB design, DSP, etc), but I've always enjoyed software more.
Last edited by videotape; 01-08-2012 at 09:05 AM.
This is tongue in cheek and using a programming language you probably don't know, but it's still informative and a good advice
Principles of OO Design, or Everything I Know About Programming, I Learned from Dilbert
So this is a codgerly rant from someone who doesn't code professionally anymore, so take it with a grain of salt:
If you don't actually have to learn OO, my best advice is not to. There's a reason that every language invented after C++ has fewer OO features.... It's all a mess.
Multiple inheritance is just bad. Single inheritance + interface implementation as in Java is ugly and can be confusing. Single inheritance on its own is gimped. Linking OO libraries is often a nightmare, yielding enormous executables that really should be much smaller considering what they're doing. Templated data structures seem like they should be good, but in reality, they're not nearly as clean as you want them to be. UML in all its monstrous glory is a godawful approach to design unless you pick and choose only the few bits of it that are any good, and then you're being inconsistent with industry practice. Though OO does provide some conveniences if you are in a large team and you just build and maintain your own little isolated classes, from the holistic system point of view, there are more ways to go wrong with it -- see the famous "shoot yourself in the foot" quotes.
Not that C is a good language for large systems; of course it was designed for system programming and it is disgusting to use on anything very big. As you are no doubt well aware, it's hard to get abstraction in C. It's just that if you are a C programmer and you switch to some higher level OO language because you recognize C's shortcomings for large systems, you will find yourself disappointed that the large-systems world hasn't gotten nearly as friendly and clean as you'd hoped.
I have no basis to give advice about the best OO language to use for EE applications, but I assume that C++ is by far the most popular OO language used in that neck of the woods.
Edit: Oh yeah, the best-looking new language I've seen in some time is Google's "Go" -- a nice small, efficient language not encumbered with too much OO-ness, but still considerably higher level than C -- but since no one is really using it yet, it's obviously not a good thing to recommend unless and until it actually becomes reasonably popular.
Python's very straightforward syntax makes it a good option for learning OO concepts, imo.
I can't agree less with Miramon. OO is essential to understand.
Now, I would say that there are also other sub-disciplines that are essential to understand (e.g. generic programming, functional programming) -- familiarity with more paradigms only makes you stronger across the board.
But there are so many critical concepts in OO (information hiding being the main one) that any programmer who doesn't have at least some familiarity with the concepts is seriously hindered.
(UML as industry practice? Not necessarily; we use it tactically where it's useful, but we don't mandate it in any strict sense. Don't conflate UML with the basic concepts of OO.)
This is the best paper I know of for really rigorously explaining what object-orientation is, theoretically. That's not really what the OP most wants, but it's nonetheless very interesting. No reason not to go to academia sometimes :-)
As far as an anecdotal overview of C++'s features beyond C, you could do a lot worse than this interview with Bjarne Stroustrup, inventor of C++. It explicitly addresses the "OO overkill" issues that Miramon cites.
If you want to really learn more about exactly why C++ is the way it is, I very strongly recommend this book by Stroustrup. If you want to just learn it from the ground up, this Stroustrup book (which I haven't read) looks like a plausible contender.
If you are coming from a C background, C++ is definitely the right next language to get familiar with. I agree that you needn't feel like you need to use every feature of the language, but it is useful to at least be familiar with why each feature exists and what kinds of problems it's intended to address.
If you want to learn more about basic structures of object-oriented design, this book is a classic for a reason.
(For reference, I am a professional programmer currently working for Microsoft in an operating systems incubation team. I actually use mostly C# these days, but am soon going to be porting portions of my hacking project to C++ to avoid real-time pauses due to the .NET garbage collector.)
Didn't the 4.0 CLR eliminate pausing GC?
So I'd just do a few hours of reading on some basic concepts like methods, instance variables, inheritance and (for Java) interfaces and then jump right in. The core concept aren't that hard. The real problem your facing is not learning "how" to use OO but rather "why" and "when". IMO you're only going to get that through using it solve real world problems. If possible, start with a project that already has a basic structure in place and then go from there.
I was in the same boat 10 years ago and what got me over the hump was working on an open source project that used OO and having a few "zen" moments where I realized why OO was worth the trouble ("oh, if I just inherit from this class and rewrite one method, I'm done!"). Later on I had some professional opportunities to work with strong OO engineers that gave me further insight. FWIW, I still consider myself a stronger procedural programmer even though I right OO most of the time. :-)
Because you already know C, either Java or C++ are obvious next steps. C++ obviously has a lot more in common with C and that familiarity will help you quite a bit but Java is a little less brittle and offers a more modern object system. Python is fine but IMO it doesn't really offer you anything over Java/C++ given that you already know C. I personally write a lot of C++ but in your situation I think Java might be the better language to go with simply because you'll find better opportunities to explore objects and existing projects with Java. C++ would be better if you were working on games.
As an uncodgerly aside, I will happily stipulate that all programmers who don't specialize in some very narrow areas should know and understand OO, no matter how lacking the general area may be.
When I scanned the OP, I got the idea he was focused narrowly on certain EE and embedded apps, and didn't quite grok that he was considering moving out of that niche. In the wide world of programming if you're not doing crappy web apps in some lame scripting environment, then you're almost certainly using some OO language.
If you know C I think C# is a great option to go with. I used to be an embedded engineer and I still mostly write C, but I worked on a C# project for a while and it's a slick language if you don't care about real high performance.
I'd suggest thinking about a good hobby project that you can use as an excuse to learn the language. For me it was sucking in the massive amounts of pitch by pitch data that the MLB publishes in XML format and creating my own stats and visualizations. It wasn't anything ground breaking, but it gave me a reason to learn the language.
I think C# is a good option because the free MS Visual Studio environment is just really nice. I mean, I write C every day and that's my jam, but once you get to know a higher level language with all the conveniences that comes with it you'll be amazed at how much you can do in a couple hours. Exploring all the libraries and tools available is intoxicating.
I think only someone who was very familiar with OO would consider this book about "basic structures" of object-oriented design. As a procedural person, I tend to regard concrete objects as the "basic structures" and Design Patterns were rather eye-opening but significantly higher concept than the idea of OO at the concrete, simple encapsulation level. If I'd tried to start out with Design Patterns I think I would have been totally overwhelmed (as is I still need to read through the first section again to really understand it).
I'd say that going from procedural to OO the first thing to understand is encapsulation which is fairly easy and tends to have a transformative effect on one's programs as is, and then probably move on to polymorphism/inheritance ideas and see the effect that has. It seems like having a firm grasp on both of these ideas and how they can work is a definite prerequisite for Design patterns to make sense. At that point Design Patterns becomes one of those "Oh, so this is how you use all that stuff elegantly and intelligently..."
Yes and no. Generally I use Java for 95% of the things I'm doing because it does nearly everything I want to do. That's not necessarily because Java is a lovely OOP language (it has some seriously irritating elements) but because there's colossal support for it. It's not so much the paradigm, more the language and the ease of getting something done.Also, for those that can do both, are you easily able to switch back and forth between both paradigms?
But, to answer your question properly, I haven't used C or C++ at any serious level for about 6+ years, and I've been a professional software developer for about 4. Depending on the IDE I'm reasonably confident I could leap into C++ and not wreak too much havoc, but I'd need a good reason to code procedurally rather than OOP-ally.
I've had much the same difficulties, as I learned about programming back when OO wasn't the norm. My brain is also a LOT more procedural than object oriented, apparently :)
I've since started developing my own game, and I've had the hardest time grasping the OO mindset. It's starting to make more sense, but it's still hard to really wrap my head around it.
My best advice is simply to DO - rather than study. But that's because I'm not good at endless reading. Most of my code is taken from examples, anyway - and I ask my brother on occasion for some OO stuff.
So, if you just throw yourself into it - you can always ask specific questions to specific problems. That's a very nice and productive approach, I find.
BTW, I use Visual Studio Express (C#) and XNA for game development. Both are free, and the environment is VERY powerful. I know you're not going for games, but C# should still be a very good choice.
This.I can't agree less with Miramon. OO is essential to understand.
If you intend to make software professionally, you need to understand OO.
Java is a much more modern language, and is much easier to learn. The same goes for C#, although I think Java has a broader usage. Either way, if you learn C# or Java, learning the other is trivial.Because you already know C, either Java or C++ are obvious next steps. C++ obviously has a lot more in common with C and that familiarity will help you quite a bit but Java is a little less brittle and offers a more modern object system.
I learned in C++, and I suppose there is some merit to doing it "the hard way", kind of like learning long division first. But, the flip side of it is.... it's like learning long division first. You're putting yourself through a lot of pain for little, if any, gain.
If you are interested in learning and applying OOP concepts, then save yourself some trouble and go with a modern language like Java or C#, which will let you (indeed, force you) to easily embrace OOP.
I agree with Timex. I think you should avoid C++ for now, and see how OOP is used in another language that doesn't have C's pointer & memory allocation baggage or C++ multiple inheritance. I found those features to be unavoidable distractions when coding in C++. Without them, you can see clearer the purpose behind all of the OO design patterns described in the Design Pattern book.
Go with Java or even PHP, which has a very similar object model to Java.
Although C# is pretty popular now, i think that the IDE(Visual Studio) gets too much in the way of learning but that's just my opinion.
Python and Ruby are options but i think they're better to use after you have some basic OOP knowledge.
As someone who works in C++ daily, stay the hell away from it as an OO language. Multiple inheritance, virtual inheritance and all sorts if stuff you should never use in practice. If you grok C than you already understand pointers and memory which is the stronger side of C++.
Like some other have said C# is really nice, and encapsulates a lot of the good stuff.
A programmer can "reinvent" OOP.
He can start writting "decent to god" C code. Then desire to make modules as ...modular and reusable as possible. So he will be inventing "modules".
Then look as his modules in disgust, because end becoming "jack of all trades", and if hard to tell if a function sould be on module X or module Y.
OOP provide "strong reasons" why a function sould be "member" of "object X", or member of "object Y".
To this point you are "abusing" the features of OOP, and writting code that looks like OOP.
I am not totally sure about the next step.
Perhaps is to look at all the "-ism". You perhaps want to have as less global variables as possible. OOP give a program the ability to have very few global variables, even zero global variables!. Of course, at this point you sould consider any declaration, even functions, as global if can be accesed globally. Anything that is globally accesable is "a global", hence evil.
A "organized solution" (not just a random one, but one that want to achieve order) to the global variables, is to think as objects as interfaces, with a public interface and a private implementation. Then expose to the global context only definition of objects, where only the interface is visible.
Even a very complex OOP program well done can feel really very very simple, because there are very few global things, or things you sould know, or things that can break.
As a bonus, OOP allow some sweet fantastic code gymnastics both in syntax and features. Changing a OOP program to output to a network pipe could be trivial, while changing a non-OOP can be tricky. Writting code that chain operations on the same object can make code both easy to read and powerful.
The process I described here may take years, while your coding style evolve.
Oh god, I've witnessed this... on systems of massive scale. We're talking millions of lines of code. As near as I can tell, they implemented everything in C, perhaps because they feared that C++ was "just a fad".A programmer can "reinvent" OOP.
Don't ever do this.
There is a time and a place where it makes sense to avoid OOP. Mostly in the performance critical realtime stuff though. Hence why you don't see drivers and interrupt handlers written in C++.
But that's a whole nother can of worms.
Java does have a real-time implementation: http://en.wikipedia.org/wiki/Real_time_Java . It's basically Java with super-strict threading rules, support for non-garbage-collectible memory and a higher resolution clock. I'm sure there are other things but I've only glanced at it.
I should recommend Effective Java by Joshua Bloch really, as when you get beyond the basic concepts of OOP you'll want to learn how to use the language effectively. But baby steps, etc.
Well, Dravalen's issues regarding performance are mainly due to the fact that once you go from OOP into non-OOP, the language itself has dropped a lot of overhead. It's inherently leaner.
Back in the day, C++ used to have the same type of advantage over Java, but that difference is virtually non-existent now. If you really want to get that kind of fundamental performance improvement now, you need to drop OOP entirely and go back to C land.
Of course, you're gonna end up writing crappier code, with more bugs, which ultimately will probably negate any performance improvements of the language itself in the longterm. :D
I don't think that is true at all. Obviously there are some horrible ways to shoot yourself in the foot with C from a memory perspective. But as a general thing I think that a good process (and code competence) is a much larger factor than just OO. Tools like valgrind have come a very long way in increasing early detection, adding prevention, and easier debugging.
In my experience having things like solid unit and functional tests with a continuous integration, sensible architecture, and developers who know what they are doing are way more important than OO vs functional.
In my experience with projects across languages is that bug injection has very little to do with the actual language being used.
Well, this thread sure made me feel less bad about hating my mandatory advanced OOP class in C++. It's not the OOP part I have a problem with, but getting something up and running in C# is so much faster than doing it in C++, it's not even funny. I understand C++ is a powerful language and very commonly used in the industry, but seeing a bunch of programmers admit that they prefer C# or Java is a relief.
Well, it's pretty natural, and in fact, writing code in non-OOP languages is harder and more cumbersome.
For example, if you have to write in C, you'll often have to be verbose like this
struct foo
{...};
void foo_do_this(struct foo* foo, ...) {...}
void foo_do_that(struct foo* foo, ...) {...}
foo_do_this(foo_instance, ...);
But in C++ (or very similarly in Java), you can just write this:
struct foo
{
void do_this(...) {...}
void do_that(...) {...}
};
foo_instance->do_this(...);
Obviously the two versions are equivalent, but the code of the C version has a lot of redundancy, while the C++/Java version has none and is thus far more elegant and pleasant to write.
Virtual functions are likewise far more concise that doing the same by hand with a structure full of function pointers.
Plus of course you get dynamically-sized arrays, dictionaries, etc. for free in the standard libraries of OOP languages, and templates/generics are often very useful and would require horrible and verbose preprocessor hacks or a code generator to do otherwise.
The ability to work with strings withouth doing any memory management is liberating. But high flexible string management is the land of scripting.
The people that choose Java to solve most problems, have problems that can be solved by Java. Are people tryiing to put nails with hammer. If you give these same people the task to write a device driver, a OS, or a AAA game engine, will choose C++, because is the right tool for this set of different problems.
If you are given a task that can be done with C++ or Java. The java one is the easier. And the easier choice is often the right one.
I love C++, because give me raw speed, and speed is ultradelicious. And I love languages like PHP because give me the ability to write large programs almost efforless.
Java, I can understand why people would love Java. Java can often help pay the bills, and anything that pay the bills is really cool. Java can be a ultra-cool OOP language with ninja powers in the right hands... but 99.99% of all java programmers are not ninjas like that. Java can let people write gigantic apps that don't crunch over his own weight, and about the 75% of all programming languages can't do that.
C++ could let you do with a computers things you don't know before if are possible. Since you are working almost on the metal level, you will make/see things your eyes will not be able to describe others. Like magic, or what is beyond magic, metamagic. Perhaps things only demo/intro dudes from the euskal party have ever seen. Compared to this, writting Java code is almost like filling tax forms.
So here. There are cool reasons to like Java, and cool reasons to like C++. But what is cool change from person to person.
Last I heard, admittedly a long time ago, a C++ struct is implemented as a fully public class with no methods, isn't it?