How to go about designing a module? - oop

How do you usually go about when you need to design a module? Till now I've taken care of how easy it is to use, how intuitive its API is, extendibility, performance and stuff like that.
But what seems fairly simple and straight-forward to me might seem over-complicated for other users. Although it doesn't happen that often, it does happen sometimes to all of us (I hope).
Are there any questions that you should ask yourself before designing a class hierarchy/API/whatever before you proceed with coding, other than the issues I already mentioned?
If you believe the question is better suited for a different section on SO please feel free to migrate it, but I'd still like an answer.
Cheers.

Your question is a very good one, and one that has answers, but so complicated that the answer is basically the experience in programming.
There are general principles to make software, but I think that here, in this short answer, I can give you one concept that you can apply. Software is a representation of a domain (such as a bank software is made to tailor the financial system, or a radar software is made to tailor the ideas and principles of radar detection). Software, therefore, is like a theory: it fits the current knowledge of your domain perfectly, allows inferences and extensions. If more knowledge becomes available, the theory should be extended, polished or made more general to accommodate this new knowledge, while still remaining valid for the previous knowledge.
Hence, all the concepts about theories apply:
satisfy the requirements imposed by your knowledge in a unified framework that sounds homogeneous and well integrated.
be simple, but look for patterns that you may make more general, and spotlight these patterns for better integration.
don't be too simple. If your software does not fit the requirements, your theory is too limited and must be extended.
allow your software to accommodate new requirements, software is not cast in stone. it mutates and evolves, accommodating the new requirements, or losing functionalities that are no longer needed.
So, software should be minimalistic but not too much, beautiful but practical.
When it comes to put into practice these directions, I suggest you to allow time for learning your domain. You can't model something that you don't understand. Learn the basics, and start from something simple, then progressively refine them. You will occasionally see that some things "feel" in the wrong place. Ask yourself questions such as
"who is responsible to do this operation?"
"Is this dependency logical and needed for this object to work, or is it just a spurious one due to bad code organization?"
"Is this high-level or low-level functionality?"
"Am I repeating this ?"
"can I change this object/layer/subsystem internally without the code outside knowing ?"
"can I extend this in the future without ruining or invalidating the past ?"
"can I test and probe this functionality easily for correct behavior ?"
"Is it easy and intuitive to understand and use ?"
"can I recombine what I already have easily and without touching to implement new behavior?"
"Is this functionality isolated so that I can show it to the outside world without the bulk of the rest of the code I manipulate ?"

You should consider SOLID Principles and here.
And about responsibility assigment apply GRASP Patterns

Related

Are KISS and YAGNI at odds with the trends towards increasingly more sophisticated patterns and practices like SOA, DDD, IoC, MVC, POCO, MVVM? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 13 years ago.
It seems to me that Agile methodologies encourage us to keep things simple, and lean, and not add complexity and sophistication until its needed. But the pace and volume of technology change encourages the use of increasingly abstract, complex and sophisticated tools and patterns to solve problems that we may not have yet (and may never encounter) in complex ways with significant learning curves and significant investments of effort.
Are KISS and YAGNI at odds with the trends towards increasingly more sophisticated ...
A car has an accelator and a brake, and a steering wheel that can turn left and/or right: it's up to the drivers to decide which to use when.
I'll keep my answer short and let the experts lay it out better...
I think that KISS applies to everything you listed. You mention increasing abstraction and complexity, which, I think, balance eachother.
The systems we are developing today must be complex, because, most of the time, the solution to a complex problem is inherently complex. However, to keep things simple, we use abstraction. Even if our complex system is built with, say, eight layers, we can follow KISS by keeping each layer simple.
For instance, to pick an item or two off your list:
SOA is not complex because we can wrap service calls in a wrapper object. This object handles the connection and makes calls, which are pretty easy to do because they simply pass parameters on.
MVC is not complex because we clearly separate our logic. We have a simple controller for directing requests and setting up data, a simple model to represent our domain, and a simple view that displays whatever data is passed to it.
However, in both of these cases, the pattern as a whole (or the system, if you will) is complex and non-trivial. It is the fact that we consider small, simple parts one at a time, and then fit them together, that lets us maintain our mental model as we work.
I agree with ChrisW's answer.
The idea is to stick with KISS and YAGNI as much as possible, but when the need arises and you need a sophisticated / complex solution, stand on the shoulders of giants and use proven patterns to guide you. These patterns and practices are meant to simplify your work, if using them is harder than the hack alternative, you should stick with the hack. Just make sure you take into account maintainability etc.
As an example, when you build the 1st version of a website it may consist of 1 or 2 main functionalities and just a few pages. You probably don't need MVC for this (even though it might be nice to start that way)
BUT, after you add a few more features and you have dozens of pages to manage along with how to share functionality between them, it might become apparent that you need MVC to better structure your application.
Similarly, if from the get go you know you will have to deal with something like returning multiple views of a common piece of data, MVC simplifies your problem by laying out a pattern for you to follow.
In summary, YAGNI now, but if you need it later then KISS by using a known pattern / solution.
Sigh.
We must have increasingly sophisticated and abstract components to match the demand for increasingly sophisticated software.
Most of us have limited brain space. We must learn to cope with our limited brains by using more sophisticated abstractions.
The alternative is not using abstractions, limiting ourselves to machine code.
Please read http://www.cs.utexas.edu/~EWD/transcriptions/EWD01xx/EWD117.html
"In spite of all its deficiencies,
mathematical reasoning presents an
outstanding model of how to grasp
extremely complicated structures with
a brain of limited capacity. And it
seems worthwhile to investigate to
what extent these proven methods can
be transplanted to the art of computer
usage. In the design of programming
languages one can let oneself be
guided primarily by considering "what
the machine can do". Considering,
however, that the programming language
is the bridge between the user and the
machine --that it can, in fact, be
regarded as his tool-- it seems just
as important to take into
consideration "what Man can think". It
is in this vein that we shall continue
our investigations."
I'm going to make a subjective answer (so sue me). I think that if you program by acronyms then you are going to run into trouble.
At the end of the day you are trying to make money for a business, or hopefully yourself. As such each decision you make is an engineering decision based on cost, time and benefits. You have to evaluate the use of a technique on the cost of implementation, maintenance etc, and make the best choice.
I think the only fair answer is that the tools and techniques chosen have to match with the desired goal of the engineering.
Its a matter of the right tool for the right job. The problem is when architects and/or developers begin to believe that a particular methodology or technology is a "golden hammer." That is when things become religious, and religion and reason do not play nicely together ;)
Oh and by the way, "agile" does not necessarily mean you don't use some of the acronyms you mention, or some framework that implements them. Those decisions are usually made far in advance of implementing the sorts of things that developers have come to associate with agile, e.g. user stories, sprints, etc.
First off, the list of acronyms doesn't really necessarily make sense - there's not really much simpler than POCO, for example...
However, KISS and YAGNI are achieved most effectively, in many circumstances, by using concepts like IoC, MVC, and MVVM - provided you use the patterns correctly.
Patterns aren't complicated, in and of themselves. It may take a bit of learning to understand what the pattern is trying to accomplish, but often, a pattern exists purely to simplify either code, maintenance, or usability - and usually all of the above. This fits in perfectly with keep it simple, for example.
IMHO, you (generally) don't want to start out with a complicated design. Could this be a local method rather than a service? Do I need an IoC container yet? This is particularly relevant when it comes to design patterns.
However, as you test and refactor your code, certain patterns (such as Ioc) will help you to achieve goals such as testability and DRY (Don't Repeat Yourself). If you know design patterns well, you can apply them at the appropriate time.
yes
-- this space intentionally left blank --

Importance of OOP concepts? Are they really used to full extent? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
The question seems pretty simple, and so is the answer. I am a developer who recently started working. So far I had taken few bachelor and master level courses on OOP. And yet I am not comfirtable and confident with OOP concepts. Recently, I was searching for employment opportunities and I found that many employers were keen to know how much confident I am on OOP concepts.
I have a very strong theorotical knowledge on OOP concepts. Although this theorotical knowledge is helping me in clearing the interviews and getting a job but when it comes to implementation I am getting dumb. If you ask me what is reflection then you will get a perfect answer from me, but if someone asks me why and where do we use it, then I get fumbled.
Now I really want to know what I should do when I am not getting an opportunity to implement all or most of the OO concepts in my projects.
Also I really feel with all the latest development tools and programming environments, many of the programmers are getting pampered to use already built components, frameworks and libraries and this is might create a vacuum of good architects.
I want to become a successful architect and for that I think I must be very strong in this area.
Then I thought of learning NHibernate where you will be dealing with objects entirely.
Now what I need is few valuable tips that would help me in grasping all or most of the OOP concepts.
It sound like you're missing real programming experience. Nothing will substitute that.
Go working, exercise, read, learn from your more experienced colleagues. Eventually you'll get it.
As for very advanced tools, you are correct. They produce code monkeys in ever increasing amounts. If you see it right now you are on a good start. Just keep to the path. Good architects will always be needed and valued.
You want to start looking at design patterns. Knowing the when, how and why of using OOP is more valuable than knowing OOP itself.
Frameworks are great and I don't fault people for using them. But, there is still a lot of room for great architects in this space. Exploit the gap of programmers knowing how to use them, but not why or when. Frameworks quickly become a hammer looking for a nail for many developers. Open source is your friend here - dive into the source code and learn them from the inside out so you really understand what's being done and why.
In my experience, you learn the "conceptual" side of development from school and the "applications" side from real experience. There is no substitute for working on the job; no matter how much schooling I've had it never equates to what I've learned doing the real work. This is why it's also a good idea to get an internship in college if you're able.
As for the value of OOP itself, I find that it's most useful in large projects and in team projects. The whole point is to break down the solution into workable "conceptual" elements which makes intercommunication between team members easier as well as visualizing the solution. Visualization is the other big pro to OOP.
One thing to note about OOP IMHO is that entry level developers tend to overuse a lot of the OOP concepts. Not everything requires inheritance. Design patterns are extremely useful but also shouldn't be over applied. Look at your problem and first try to think of a solution on your own then compare it to known patterns and see if they provide a better answer. Simplicity can't be overrated.
Also, playing with tools like UML editors and Mind Mappers (such as XMind) are helpful in getting into the right frame of mind.
Check and see if there are any programming groups around you too; I find it's a good way to meet people that you can talk programming with and another advantage of OOP is its much easier to communicate programming ideas with.
Your next stop should be to look into design patterns (Applied OO). For an introductory text, check out Headfirst Design Patterns.
Interesting question. To some extent I've grown up with Object programming, I've evolved as the various frameworks have evolved, I'd never before considered how it would feel to come to a landscape where so many sophisticated frameworks already exist. Their very presence tends to inhibit that degree of fumbling and stumbling and generallly getting it wrong that leads to deeper understanding.
My perception though is that serious development is still a matter of good design, it's not all just fill-in-the-gaps, hey IOC framwork tell me what to do, programming.
You can enhance your theoretic knowlege by studying the "how" of the framworks you use. But I guess what you need is practical experience, can't comment upon what's open to you in your place of work, but if you can't get it there you may need to do some "hobbyist" or open source development.
One thing I would recommend is trying to get involved in design discussions, try to get your designs reviewed by experienced developers. With any luck they may even say: "hey why didn't you use reflection there ..."
It is the 'thinking' that is important, in OOP one needs to change thinking
while going about programming/developing in oop environment or using OOP
paradigm.
I have faced many a times this question myself: why use OOPL or
Object Oriented Programming Language when I can develop software in Procedural
Programming Language? Why use OOP methodology at all? What benefit does it have
what other non-oop doesn't?
I read from many sources (numerous books and articles on the subject to name!)
to trace the real reason, to hit the fundamental underlying idea or principle
for its being there as a paradigm of software engineering. I think what I found
is simple and that's why I suggest to bring a change in thinking.
If we look around we see things that surround us and the things we interact
with, directly or indirectly. We recognize them with names, we gave them.
Whatever the things are, either they exist in real plane or conceptual plane
and we 'know' them 'recognize' them and interact with them. And importantly we
'name' them. This naming is important because to interact with the 'things' and
for that knowledge of that interaction we need 'Names'.
What have you eaten today? Chocolate and coffee. So you have 'interacted' with
chocolate and coffee. Now Chocolate and coffee are edibles we have (humans)
have given names and with those names we recognize them. And also, we, in our
knowledge of our interaction with them - lets say keeping record of our
interaction with chocolate and coffee, know them with names as having
interacted with.
Interaction is a general term I am using here. Actually in our case, in the
example, you have performed an 'action' - eating. Through 'eating' action you
have interacted with chocolate and coffee. Now think this way, you, chocolate,
coffee are entities in the real world through an action came in interaction.
You may say a 'Process'.
What course Alice has enrolled for? Computer Science.
Computer Science does not have a real existence in the world in the sense a man
exists or a tree or a house, or coffee cup or other 'tangible things' exist. It
is a subject, 'conceptual thing'. The study of computer science has some
'topics' to be studied (or to have interaction with through our mental
faculty/processes)e.g discrete mathematics, design and analysis of algorithms,
Data Structure etc. Together they are named, as a subject of study, 'Computer
Science'. Now Alice 'study' (interaction) Computer Science.What is happening
here? OK, if We now think this way and say that Alice is a thing, an object.
Computer Science is a thing, an object.
Coffee is an object. Chocolate is an object. You, again, are an object. We find
that objects interacting with objects. Fantastic! One may exclaim! That's the
real world scenario! Actually it is a generalization reached through
Abstraction.
It is nothing but -at the surface level at least- naming with
meaning. Or you can say 'meaningful naming'. It is a process. It is so natural
and obvious to us that we simply overlook it.
In OOP we simply have to bring ourselves to this form of thinking process,
knowing and reminding ourselves that "Objects interact with Objects". Oh!
There are more than thinking only this. You have to remember that an object
may interact with itself! Think of you, what are you doing when you are
thinking? Yeah! And there is another very important thing I shall come to
in due time. Though I think it is obvious. But in due time. OK. What we
really do with computers? Actually we solve problems. Particularly those
problems which we try to do or solve in our minds. In broad sense we are
simulating mental processes in a machine, so designed by us. Remember AI is
still a far off thing in reality and there are debates both scientific and
philosophical, on whether a computer can become Intelligent at all. Another
way of putting it whether a computer can really simulate a real mental
process. But that's not for us to take here. Leave it!
If we want to solve problems in real life through a computing device we
would like to go as closely in representing the real life as possible.There
comes the term in OOP 'real life modelling'. It can be seen that in solving
real life problems, be it launching a space shuttle, or keeping the customer
and product sale information for processing we do abstraction and do
calculation, which is another form of abstract process, in turn we deal with
objects mentally, in our mind. So we represent real life objects (conceptual
objects such as numbers) in abstraction and deal with them with abstract
processes, as in mathematics. In computer too we would like to represent
objects and also like to represent processes in the form of objects. So here
comes the Object Orientation so to speak to software engineering. Now comes
that 'due time' to deal with another aspect of OO.
To go back to our example, What did you eat? Eating is an action, a form of
interaction. Which can be thought of as process which again can be thought of
as an Object, like a processes is thought of and represented as 'function' or
'routine' or 'procedure' in Non-OOPL. In OOP we can represent (abstract away)
eating as a process embodied as an object. Similarly studying is an object. In
the same line of thinking 'thing' and 'process' both be thought of as objects
and be represented in virtual plane which is computer memory. Therefore
Alice-an Object-Studies-an object-Computer Science-an Object is valid in OOP
parlance as far as our argument goes.
Can we write a piece of code here? Lets try.
class Alice {
private String name;
private String address;
private String stdID;
private Course courseOfStudy;
... other codes...
public void studies(Course sub) {
courseOfStudy=sub;
}
...
public Course getStudyCourse() {
return courseOfStudy;
}
}
class Course {
codes....
}
This way in OOP (here Java code) one can go about writing codes. I have just
given a simplistic coding. One can come up with better coding and design
approach depending on the software in mind to be written. In OOP design is very
important. So in thinking which I mentioned at the beginning the change should
be brought in. That's important! I prefer to go this way when it comes to OOPL
or OOAD, "everything is object".
Well that's what I wanted to say. You may or may not like it but comment and
say your mind.

How do I explain loose coupling and information hiding to a new programmer? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
How do I explain loose coupling and information hiding to a new programmer? I have a programmer who I write designs for, but who can't seem to grasp the concepts of loose coupling and information hiding.
I write designs with everything nicely broken down into classes by function (data access is separate, a class for requests, a controller, about 5 classes total). They come back with a modified design where half the classes inherit from the other half (and there is no "is-a" relationship), and many public variables.
How can I get across the idea that keeping things separate makes it easier to maintain?
Ask him if it's a good idea to let you borrow $10 by giving his wallet to you for a moment and taking the money yourself.
The problem is your expectations, not the developers lack of skill. You talk about loose coupling and information hiding as if these are simple facts or mechanical techniques - they are not. Software development is a craft and the only way to get better at a craft is to practice it and slowly and incrementally improve.
You are looking for a shortcut. You want the developer to experience an "ahah!" moment and suddenly see the wisdom in your design. I say, don't hold your breath.
Adopt the mindset of a mentor. If you want him to improve his design skills, don't "hand" him a design, let him to design it! Then review the design with him. This will give him experience, a deeper sense of ownership and more willingness to listen to your suggestions before he is knee deep in implementation.
An aside - I notice that people look for these shortcuts all the time with abstract skills but not with more "physical" skills. Take tennis for example. If you were a tennis coach and a new player kept hitting his forehands long, you wouldn't just show him a YouTube video of a Roger Federer forehand and expect him to "get it". A great forehand takes YEARS of experience as you learn the feeling and use it in different scenarios - its not your muscles learning, its your brain. It is no different with software design. You get good at it by doing it over and over again. You slowly learn from your mistakes and get better at appreciating the consequences of each individual design decision.
The best way to explain these kinds of concepts is to use analogies. Pick something non-programming related and use that to explain the abstract design concepts.
The following image is pretty good at explaining the need for loose coupling:
Try to come up with stuff like this that will amuse and pertain to your new programmer.
Theory will only get you so far.
Make him try to add new features to code he's written a while ago. Then rework the old code with him so it's loosely coupled and ask him to add the same features.
He will certainly understand the avantages of writing good code.
There's nothing like a physical analogy. Walk out to your car and point out how everything complicated, hot and dangerous is pretty well isolated from the fragile human. Sit in the driver's seat and point out some of the important gauges; for example, the coolant temperature, tachometer and speedometer. Note how the gauges are remarkably similar: they all take a scalar value (from somewhere) and represent it by moving a needle to a position between min and max.
However, if you think about what's being measured, the strong motivation to maintain that isolation (aka loose coupling or information hiding) becomes a lot more obvious.
"How would you like to measure the coolant temperature? By looking at a gauge or by sticking your finger into near-boiling liquid?"
"How would you like to measure the engine rotational speed? By looking at a gauge or by letting a multi-thousand RPM crankshaft rip the flesh from your bones as you try to estimate it by hand?"
"How would you like to measure the car's speed? By looking at a gauge or by dragging your foot on the ground as you're roaring down the highway?"
From there, you can build on the concepts of "your coolant temperature gauge is-a gauge. It isn't-a boiling liquid" and so forth to more complicated concepts.
Loose coupling: The parts of a watch may be replaced by others with out breaking the whole watch. For instance you can remove one hand and it will still work.
Information hiding: The clock hands doesn't know that behind them there's a machinery.
Additional concept
High cohesion: All the elements in the watch "module" are strongly related. In this specific scenario, a battery would belong to another module or namespace.
Show him this presentation. Though it's mainly about DI, it's downright brilliant and up to the point.
I would try sitting down with him and working through a couple of peieces of code with him looking over your sholder and you explaining why you are doing what you are doing as you go along. I've found this is normally the best way to explain things.
Ask him to make a change you know it will be hard because of his design and show him how that would happen using yours.
If he complains, tell him the truth: business will ask more bizarre changes, it's a matter of time he will see that.
Just don't talk to him. That should teach him about information hiding. ;-)
I like a credit card for an example.
You have a credit card.
A credit card represents your credit history. It has a balance and a APR. It has permissions and an entire financial state. It has a id, an expiration date, and a security code. The magnetic strip summarizes all of this.
When you go to your local credit-card-accepting establishment, they don't need to know that. They don't want to know that, and it is often very dangerous if they do know that. What they need to "know" is that there is a magnetic strip which will take care of all of this, and (sometimes) that the person holding the card has id to match the name printed on the card.
Giving them more information is either (in the best case) useless, or (in the worst case) dangerous. Requiring them to know which bank to check with, making sure they know how to calculate your particular APR, or allowing them to check your balance is simply silly at that point.
If he's misinterpreting your designs, perhaps a couple pair-programming sessions will be enough to get them on track. I do have to agree with #ThomasD and will expand upon it -- the encapsulation going on here could be you. It could be a simple case of misinterpretation instead of them not understanding the concepts.
I think that OO concepts really need to be learnt practically. One really needs to do these things to understand. I go to school (engineering) and most of my peers don't really get the concept. They know in general that loose coupling is 'good' but not why. They also don't know how to achieve loose coupling. I am working on my final year project now and I got through to them by making them part of the design process. (It helped that they really did understand how and why and had an inkling of its importance)
Given your situation, here is what I would suggest:
1. Make them follow your design exactly (at least for a couple of weeks). If they want to deviate, have them discuss what and why with you. [Time constraints may not permit this].
2. Sit with them on whichever part of the design you are doing next and explain some o0f your design choices to them, with examples. Somethings that are obvious to you may need to be pointed out to them.
3. Be on the lookout for examples, both of good design and bad design and show them how that works better.
The most important task here is of delegation. You have to show them what good code looks like, maybe train them for a couple of hours. Then you agree on when to review and how you can help them (whithin your limited free time (?)) do the task well. The main thing is to get them to identify with and understand good design. Doing these things will help them 'buy-in' to the design. Once they feel it is their design, I am sure they will do better work.
Overall, I think you need to put your foot down and get them to code it right, without stifling their creativity.
I don't really have too much experience in the area. I am just giving my opinion on the subject, based on what worked for me. I hope this helps.
Note
I'd like to add that OO concepts can be learnt from books, while their application can be learnt only by practice. I have added this note in response to a comment by Christopher W. Allen-Poole.
Well if you have to explain it to them then I'm forced to ask: are they really a programmer?
Tell them they need a "college do over"?
That's a hard one because it's such a basic concept. Personally I wouldn't want to handle it because it's like someone is getting paid to learn stuff they should already know but life isn't always ideal.
I'd approach it by finding a problem that's simple enough to solved relatively simple. Public variables are usually handled best by trying to find the source of a problem when you can't see what's changin gthe variables. You can design a scenario for that.
The over-inheritance may not be their fault. They may have learnt in a course designed in the 90s that's trapped in the idea that "everything must inherit". I remember the old examples of Manager extends Employee. It's just BAD. Thing is people get taught this nonsense. Still.
For C++ the Scott Meyer Effective C++ series is probably worth poniting them to (assuming they can be bothered to read something). For Java, Josh Bloch's Effective Java ("favor composition") is along the same lines. Not sure about C#.
These sorts of books give a better approach to inheritance vs composition and also give some good examples of why inheritance is (as Josh Bloch puts it) an "implementation detail". I've also heard it described as "inheritance breaks encapsulation".
I saw a good example once of inheritance vs composition with extending the capabilities of a List in Java and how inheritance required you to know implementation details of the parent to do correct whereas composition didn't. I'll see if I can find it.
If you do Unit Testing, explain it in terms of test-writing. Alternatively, Abstract Classes and Interfaces both use loose coupling and information hiding to great effect. If you explain it to him in terms of other concepts he may already have a handle on, he'll be more likely to appreciate the concept quickly.
Programs are systems of interacting parts.
For a system of interacting parts to work together requires connections between these parts.
The more connections, the more costly the program.
For a fixed number of parts, a system whose parts are unnecessarily connected is more costly than a system whose parts are necessarily connected.
Unneccessary connections can only be formed in a system whose parts are unnecessarily exposed to connections from other parts.
Minimising unneccessary exposure of parts to connection from other parts is fundamental to cost-effective program development.
Loose coupling and information hiding are the fundamentals of connection-exposure minimisation.
This is not optional knowledge for a programmer.
This is fundamental.
You cannot be a cost-conscious programmer without this knowledge.
Asking how to explain loose coupling and information hiding to a new programmer is like asking how to explain surgery to a new surgeon? Or to explain architecture to a new architect? Or how to explain flying to a pilot.
If your, 'New programmers,' don't know loose coupling and information hiding, then they are not, 'New programmers;' they are potential programmers.
Curiously, it probably won't help to tell them to read the original two papers:
i)Loose coupling: 'Structured design,' by W.P. Stevens, G.J. Myers and L.L. Constantine.
ii)Information hiding: http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf
Just like the move from 16 bit to 32 bit windows applications where processes were given their own address space. This stopped any other process from being able to kill your application when it "accidently" walked over your data.
Moving processes to different address spaces was like treating each process as a class, and hiding the memory internally and decoupling the processes by forcing interprocess communication to only happen via an expected interface ( eg Windows Messages ).
loose coupling means the external code should use the object of derived non abstract class through abstract base class. if any change occur in set of class on which it depend then not neccessory to change in external code i.e. external code really exhibit loose coupling.

How to develop *real life* oop skills?

I've been studying OOP for quite a while now and I have a good grasp of the theory. I read the Head First book on OOP and, while it reinforced a lot of the theory, I found the case studies to be somewhat trivial.
I find that I'm applying OOP principles to my code each day, but I'm not sure if I'm applying them correctly. I need to get to the point where I am able to look at my code and know whether I'm using inheritance appropriately, whether my object is cohesive enough, etc.
Does anyone have any good recommendations (books, online guides, blogs, walk-throughs, etc.) for taking the next step in developing solid OOP skills?
I am working primarily in .NET (visual basic), but I welcome suggestions that incorporate various platforms.
Read Refactoring by Martin Fowler, and apply it to your own work.
It will take you through a litany of malodorous characteristics of software code that describe how to detect improperly constructed classes, and even more importantly, how to fix them.
Consider looking into Design Patterns. Although it seems like they aren't commonly used in enterprise applications (I've seen them more commonly used in API's and Frameworks than embedded into enterprise code), they could be applied to make software simpler or more robust in a lot of situations if only developers knew how to apply them.
The key is to understand the design patterns first, then with experience you'll learn how to apply them.
There is a Head First book on design patterns that teaches the concept pretty simply, although if you want a book that really covers design patterns in detail, check out the Gang of Four design patterns book, which is basically what made design patterns mainstream and is referred to almost every time the topic is brought up.
Design patterns can be applied in pretty much any object-oriented language to some degree or another, although some patterns can be overkill or over engineering in some cases.
EDIT:
I also want to add, you should check out the book Code Complete 2. It's a very influential book in the world of software development. It covers a lot of different concepts and theories. I learn something new every time I read it. It's such a good book that if I read it every 6 months to a year, I look at it from a different perspective that makes me a better programmer just by re-reading it. No matter how much you might think you know, this book will make you realize just how little you really know. It's really a great book. I can't stress how much you should own this book.
If you already have the basics, I believe only experience will get you further. You say you are not sure if you are applying the principles correctly, but there is no one correct way. Code you write today, you'll look at in 6 months time, and wonder why you wrote it that way, and probably know of a better, cleaner way of doing it. I also guarantee that after 10 years, you'll still be learning new techniques and tricks. Don't worry too much about it, it will come, just read as much as you can, and try and apply what you read in small chunks.
I am currently half-way through the following book:
http://www.amazon.com/Applying-UML-Patterns-Introduction-Object-Oriented/dp/0131489062
I cannot recommend this book strongly enough in terms of learning a real-life, professional-grade, practical approach to drafting and applying a well-formed and iterative design strategy before diving into code.
I, too, read the "Head First" book and felt that I was much better off for having read it.
After having a few years of working-world experience, I now view the Craig Larman book that I am recommending to be a perfect "next step" for me.
About the Presence of "UML" in this Book Title:
Whether you have positive feelings or negative feelings about UML notation, please do not let that influence your decision to buy the book (ISBN 0131489062) in either direction.
The prominence of "UML" in the title is misleading. While the author does use and explain UML notation, these explanations are extremely well-woven into relevant design discussions, and at no time does this book read like a boring UML spec.
In fact, here is a quote taken directly from the book:
What's important is knowing how to think and design in objects, which is a very different and much more valuable skill than knowing UML notation. While drawing a diagram, we need to answer key questions: What are the responsibilities of the object? Who does it collaborate with? What design patterns should be applied? Far more important than knowing the difference between UML 1.4 and 2.0 !
This book at times seems like it is "speaking to" a lead architect or a project manager. What I mean to say by that is that it assumes that the reader has significant control over the planning and direction of a software project.
Nonetheless, even if you are only responsible for some very small piece of your company's projects and products, I would still recommend this book and encourage you to apply some "scaled down" modifications of the book's advice to your piece of the project.
My OOP epiphany came from Grady Booch's book, way long time ago. Suddenly I realized why objects were good.
While polymorphism is cool, encapsulation is 75% of why objects are cool. It is sort of like an interface: you see the buttons but not the wiring. Before objects, only the most disciplined coders kept their grubby fingers off the internal bits of other people's procedures (it was called "structured programming").
Object make it easy to Do the Right Thing. Inheritance and polymorphism are little bonuses.
One way to learn about objects is to read other peoples' code. I learned a lot by reading the source code for the Delphi VCL framework. Even just looking at the documentation for Java will help you see what a single object class should do and how it is designed to be used by other objects.
Start a project of your own and pay attention when you want to sub-class your own classes and find that you have to go back and break up some protected methods so you can override just one piece of a process instead of replacing all of it. See how ancestors talk to descendants by calling abstract functions. In other words, go make a lot of mistakes and learn from them.
Enjoy!
Frankly, re-reading old David Parnas papers on information hiding helps me get in the right state of mind. The case studies may not be directly applicable but you should be able to get some useful generalizations out of them.
My epiphany happened when I tried to implement a very OO problem (dynamically and recursively building SQL statements) in VB6. The best way to understand polymorphism or inheritance is to need it and not be able to use it.
One thing that will definitely help you is working on a well-known, respected open source project. Either dig through the source code and see how things are done or try to make some additions / modifications. You'll find that there isn't one style or one right answer for most problems, but by looking at several projects, you'll be able to get a wide view of how things can be done. From there, you'll begin to develop your own style and will hopefully make some contributions to open source in the process.
I think you have to attempt and fail at implementing OO solutions. That's how I did it anyway. What I mean by fail is that you end up writing smelly code while successfully delivering a working solution. After it's written you'll get a feel for where things didn't quite feel right. You may have some epiphanies, and/or you may go and hunt for a slicker solution from other programmers. Undoubtedly you'll implement some variation of standard design patterns by accident. In hindsight, a light will click on (oh! so that's what a visitor is for), and then understanding will accelerate.
As others have said, I think tooling through some good OO open source code is a good idea. So is working with more experienced programmers who would be willing to critique your work. However understanding comes through doing.
You might want to try to read (and write) some Smalltalk for a while. Squeak is a free implementation that can show you the power of a fully object-oriented environment (unlike java or .net). All library code source is included. The language itself is incredibly simple. You'll find that java and c# are slowly adding the features well-known to Smalltalk since 1980.
Tortoise HG is extrodanarily well designed piece of OO open source software (written in Python).
If you already understand the basics, building something from scratch in a fully object oriented language will be a good step in fully understanding OOP software architecture. If you don't know Python, Python Essential Reference will take you through the language in full in a few days to a week.
After you understand the language take a look through the software above and you'll have all sorts of epiphanies.
To understand basically anything thoroughly, you need to have a decent knowledge of at least one abstraction level above and one level below it. In the case of OO, others have mentioned design patterns as the layer above OO. This helps a lot to illustrate why OO is useful.
As far as the layer below OO, try to play around with higher-order functions/late binding for a while and get a feel for how these relatively simple constructs are used. Also, try to understand how OO is implemented under the hood (vtables, etc.) and how it can be done in pure C. Once you grok the value of using higher order functions and late binding, you'll quickly realize that OO is just a convenient syntax for passing around a set of related functions and the data they operate on.

Formal Methods and Enterprises [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
So...
I teach formal methods in software engineering. I also teach "agile methodologies". Most people seem to think this is contradictory. I think it makes a lot of sense... I also work for a company, where we need to actually get things done :) While I can apply my earned skill points on "specification" in a day-to-day basis, my colleagues typically flee away from the word "formal".
I used to think that this was due to the intrinsic way we learn how to program: we are usually driven to find a working solution, not to understand the problem. Then I thought this was due to the fact that most people in the formal community are not engineers, but mathematicians or computer scientists. Nowadays, I wonder if it just because the formal-methods community hide behind some kind of "obfuscation" law to use all the available UNICODE symbols, actively develop rude, unesthetic tools, and laugh in the face of standards.
Yes, I've been moving from a "blame them" to a "blame us" perspective ;-)
So, my question is: do you use any kind of formal methods in your company? Have you introduced them, or were they pre-requisites? What techniques do you use to clear the fog of mathematics from people's fears and incite them to use formal methods? What do you think current tools are lacking for a more general usage?
The key to getting people to buy into any methods or methodologies is to show them how it solves problems they are having. If they can see it will make their lives better you have a much improved chance of getting them to adopt the techniques.
And if you can't show them that, perhaps you wanted to adopt the methods based on philosophy rather than practicality. Unless the others share your philosophy then you're not going to get anywhere. And perhaps you shouldn't.
Over the decades there have been a great many methodologies. Newer ones always address the shortcomings of the old ones, yet projects still get in trouble and fail. Why? Because the rock stars that come up with new methodologies are rock stars, and have made a new methodology precisely because they understand the underlying issues and how to apply them. Those who come after tend to blindly follow the recipe, and it doesn't work so well.
So I think the best thing is to teach about the underlying problems and then show how various methods attempt to deal with those problems. The differences in companies, projects, and teams is so great that no one methodology can be applied successfully to all combinations. Learning to choose an appropriate tool and apply it well is crucial.
Thank you for all contributions. They are very insightful. Allow me to flame a bit (don't take it personal, though :-)
Most people seem to think that formal methods are just about program verification. Or critical systems. This may be true if we pursue the ultimate cliche: to prove we are doing the program right (v.s. validation, which asks, as a contributor said, if we are doing the right program).
But consider model finding/checking tools, such as Alloy. Learning to use a tool like this takes a negligable ammount of time for anyone used to UML and OO. Still, it can give you immediate insight over your model. It usually takes no more than 10 minutes to find a counter-example over a small enough subset of the model one's trying to use (and that includes describing the model in Alloy in the first place).
Take requirements engineering as an example. One usually draw a lot of UML. Few people use OCL, though, and many business rules are informally annoted in natural language. Why? Time constraints?
Now consider the fact that the majority just uses her/his gut-feeling to prove that a model is satisfiable. Again, why? I can take the same amount of time (probably even less, since I don't need to care about drawing aesthetics) to write that model in Alloy, and just check for satisfiability? And what kind of mathematics do I need to now? "Predicates"? Fancy name for IFs and booleans ;-) Quantifiers? Fancy names for ForEachs()...
What about big information systems? They don't need to be critical... Just try to analyze in your head a conceptual (not implementation!) diagram with over 600 classes. I see many people banging their head in the wall with easy-to-make model mistakes because they missed some constraint, or the model allows stupid things to happen.
The fact is, one does not need to use formal approaches from head to tail. Granted, I could prove a whole application in Coq, and certify that it is 100% compliant with some specification. This may be the Computer Scientist/Mathematician approach.
Still, with a GTD philisophy, why can't I delegate some tasks for the computer and allow it to help improving my development? Is it really a matter of "time", or plain, simple lack of technical abilities and will to learn/inovate?
Working with line of business IT development in an enterprise means having to transfer knowledge about the business from actual business people into the heads of developers. While I myself find abstract maths to be one of the greatest pastimes there is, it's a terrible communications tool. And communications is what it's all about. While I might conceivably have some success convincing IT people to embrace more abstract notations, I basically have no chance with the business people.
While there are some areas where I can see a role for formal methods in an enterprise (math- and logic-heavy specialist software, significant need for provable properties as in safety critical software) they provide little help with getting correct requirements on e.g. how to fulfil a customer order by issuing one or more supply orders to a set of possible external or internal providers.
I think the jury is still out on model based approaches and domain specific languages. I think they will succeed or fail depending on whether they provide quicker feedback from IT to the wishes and needs of the business side, and whether they presume business people will have to do any significant studying.
Technology is easy. Communication is hard. Formal methods may help us do things right, but those I've seen do nothing to help us do the right things. (Yes, these are cliches, but that's because they're inescapably and painfully true.)
I'm taking a course on 'Specification and Verification'. As part of the course structure we are doing the following-
1. Learning tools like PVS(Prototype Verification System) http://pvs.csl.sri.com/ and SMV(Software Modeling and Verification) http://www.cs.cmu.edu/~modelcheck/smv.html
2. Apart from that we do dissect accidents which happened because of software failures. For e.g. - Failure of Ariane V
I feel formal methods are more applicable to scenarios where the failure cost is more than the design cost. And it seems apt to use them for softwares being used in critical systems. I guess it is used in avionics, chip design etc. and the current automobile industry is also drafting it into practice.
I have tried to get people to embrace formal specification methods a few times (Z and Alloy) and have made the same expirience that you have: Most people, while feeling that they serve a useful purpose, are very uncomfortable using them for actual work.
Funny enough, the same people are more than happy to produce utterly useless UML diagrams in ginormous quantities.
I think there are two main reasons for this:
a.) Many developers are uncomfortable with the level of abstraction required by a formal approach. The fact that most entry-level mathematics education is all calculus and non discrete-mathematics might have to do something with this.
b.) Formal methods require a very bottom up design aproach where you design your core model from the ground up and make it airtight and then connect it up to the actual user requirements by providing an interface on top of it. Since we tend to have requirements drive development efforts, a top-down approach feels more natural although it often leads to inconsistent models. It's like retrofitting a basement underneath your house after it has already been built.
Formal methods make no sense in systems where the cost of failure is low.
In a production web application, you've got multiple front-end boxes, multiple back-end boxes, multiple database boxes - if a program on any one of them fails, it's a non-event. Hardware is so cheap that you can build these systems for far less than the cost of formally specifying all your software.