The gist of my problem with Software Engineering People is that it somehow flicks the poetic part of the person and ends them talking irrationally. Compare this to any other thread on algorithms and compare the focus of the posts here and there. There's some amazing difference. I prefer to deal with S.Eng. just the same as I do with algorithms, with just the right amount of alertness and rigor. Otherwise it wouldn't qualify a bit to the description of engineering. The following comments may seem rude, but are necessary.
to each purpose its requirements
What are you talking about? I have not eluded into any purpose for that statement to have any additional value.
in software engineering you cannot go "by the book" this kinda defeats the whole purpose of it
software engineering methods vary a lot depending on the purpose and function of the software you are to develop
I didn't talk of any right-from-the-book solution, or a canonical problem to speak of. I still don't see what you're eluding to.
do not blindly follow what should be considered as guidelines rather than rules.
What are you talking about here? Did I already start following something blindly? What merits do you have to start lecturing me about this?
a simple question and i'll let you answer it
do you think creating a class Person in a business oriented software to compliment the table PERSONS in the database as being OOP programming ?
Why are you answering a question, an exercise with another question. Does that add to the wisdom you've been bestowing upon us? I don't see the relevance of the RDBMS and OOP impedance mismatch to the simple corner case I've set before you guys.
This baffles me. It's a little bit weird to create types to represent relations between two objects, where when of them is no more necessary, the types created become totally superfluous.
Abstraction is a powerful tool. Whenever you write a program, you extend the language you're using in order to be able to handle the concepts of your program.
Though your reply is somewhat relevant, what I meant was the observation that when two classes need to interact their representation is necessary, however when one of them is no longer present in a program the representation of the other is superfluous.
Plain C doesn't have a "radian" data type, for example, but if I'm writing a program that does trigonometry, I'm going to define "radian" just the same because when I talk about trigonometry, I want to talk about radians and not floats, even though internally they have the same representation. We define abstractions because they allow us to think about our problem on a higher level, the computer couldn't care less about them :)
Ok, now we're getting somewhere. The computer couldn't care less if I write in ASM. So the statement is irrelevant. When you define a type as radians, and map it either to floats, to doubles, or to a fixed point representation (using an int) it indeed may make sense to define a type just for the "radians".
I find my main problem is that I try to over-engineer a solution when the problem can be solved in much less time with much less code, even if that code isn't "beautiful" by my (very skewed) standards!
Software engineering, contrary to much people's beliefs, is not an exercise in aesthetics. Instead it's an exercise in
engineering. You must be evaluating the quality of the structure of a program by the merits of maintainability, extensibility, flexibility, organization. I am sure "beautiful" in this sense is your own gut perception of those very standards, however, materializing those and evaluating them would prove invaluable for your understanding of your own guts.
Object Oriented Design is meant to represent the concepts in objects which is assumed to be the closest thing to how we think about the world, usually as objects. Now there are principles and there is how you put them into use. If you find yourself unable to justify the existence of a class, then it shouldn't be there, and this usually means you approached the problem in a wrong way.
Your statement about representing objects as they are in the real world is rather skewed and useless unless in some very exotic academic situations. The fact is, OOP is taught in a setting of the real world as to make it more approachable to students. However when the hammer hits the steel, it's usually an exercise of encapsulation, decoupling and reuse. That's why we have Observer Patterns, Factory Patterns and what not. Though they have real life counter parts, their existence is not justified by the existence of real factories.
For instance, in the problem you describe, there is no need for 2 types representing different representations of the same thing. Since angles are angles, be they in radians or in degrees, then all you need is one class. This class has different representations of the same value. You could store the angles in radians and have 2 properties displaying that value, in radians or in degrees (by converting). You could also have static factory methods like FromRadians() and FromDegrees() that would instantiate approprate Angle objects for you.
What do you mean I don't need them? Right out from the start, this is not a question of need. It's a matter of offloading work to the compiler. Having FromRadians and FromDegrees signifies that I am keeping the user's mind busy with tracking variable's types. Instead if I receive a Degrees object, I can at runtime know for sure that it will either give a compiler error or be implicitly converted to Radians (depending on the existence of casting operators or default constructors).
Finally, I think design patterns tackle such issues and others like determining which types are the most appropriate place to put methods, where instantiation is best handled, etc... There are also books on these topics.
Books usually focus on higher level concepts, and try not to dive deep onto such kinds of exercises (for plenty of reasons).
OOP Saves my butt almost everytime I program something that goes a little bit beyond what is thought to be "straight forward". Abstraction makes it easier to grasp the concepts you're trying to convey in your code, the objects you're playing with and the relationships amongst them. In most cases, and due to lack of proper planning before I actually jump into code (which reminds me, I should hold back my adrenaline everytime I get into a new project), I end up writing several classes that have so much in common. Then I realize that I should've used some inheritance and/or composition to make my work easier. Eventually, I either end up refactoring huge portions of my code, or I leave it as is because I'm too lazy to do it.
I don't see how this is greatly relevant to the question itself.