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.
Related
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
In the database world, we have normalisation. You can start with a design, crank the steps and end up with a normal form of the database. This is done on the basis of the semantics of the data and can be thought of as a series of design refactorings.
In object orientated design, we have the SOLID principals and various other adhoc guidelines towards good design.
Do you think it is possible to define the equivalent of normal forms for OO, such that a series of refactoring steps could move a procedural piece of code (or poorly factored OO design) into a correct (in some well-defined sense) formulation with the same functionality?
(NB. Happy to make this community wiki)
It is a possibility, but highly unlikely.
Context
First, in the days when the Relational Model came out, people who worked in IT were more educated and they esteemed standards. Computer resources were expensive, and people were always looking for the best way to use those resources. People like Codd and Date were giants in an industry where people were high tech.
Codd did not invent Normalisation, we were Normalising our non-relational databases long before Relational came along. Normalisation is a theory and practice, published as the Principle of Full Normalisation. We were Normalising our programs, we considered accidental duplication of a subrotine (method) a serious error. Nowadays it is known as Never Duplicate Anything or Don't Repeat Yourself, but the recent versions do not acknowledge the sound academic theory behind, and are therefore its power is unreallised.
What Codd did (among many things) was define formal Normal Forms specifically for Relational Databases. And these have progressed and been refined since then. But they have also been hijacked by non-academics for the purpose of selling their gear.
The database modelling that was invented by Codd and Chen, and finished by Brown had a solid grounding. In the last 25 years, its has achieved Standardisation and been further refined and progressed by many others who had solid grounding.
The World Before OO
Let's take the programming world before OO. We had many standards and conventions, for modelling our programs, as well as for language- and platform-specific implementation. Your question simply would not apply in those days. The entire industry understood deeply that database design and program design were two different sciences, and used different modelling methodologies for them, plus whatever standards applied. People did not discuss if they implemented standards, they discussed the extent to which they complied with standards; they did not discuss if they modelled their data and programs, they discussed the extent to which they modelled their data and programs. That is how we put men on the Moon, notably in 1969.
Dawn of OO
OO came along and presented itself as if no other programming language or design methodology existed before it. Instead of using existing methodologies and extending or changing them, it denied their existence. So, not surprisingly, it has taken 20 years to formulate the new methodologies from scratch and slowly progress them to the point of SOLID and Agile, which is not mature; the reason for your question. It is telling that more than twenty such methodologies have flashed up and died during that time.
Even UML, which could have been an outright winner, applicable to any programming language suffered the same disease. It tried to be everything to everyone while denying that mature methodologies existed.
Demise of the Industry
With the advent of MS, the attitude of "anyone can do anything" (implication: you do not need formal education or qualifications), that quality and pride of profession has been lost. People now invent things from scratch as if no one on the planet has ever done it before. The IT industry today is very low tech. You kow, but most people reading these pages do not know, that there is one Relational Modelling methodology, and one Standard. They do not model, the implement. Then re-implement. And re-implement. Re-factoring as you say.
OO Proponents
The problem was that the people who came up with these OO methods were not giants among professionals; they were simply the most vocal of an un-academic lot. Famous due to publishing books, not due to peer acknowledgement. Unskilled and unaware. They had One Hammer in their toolkit, and every problem looked like a nail. Since they were not formally educated they did not know that actually database design and program design are two different sciences; that database design was quite mature, had strongly established methodologies and standards, and they simply applied their shiny new hammer to every problem, including databases.
Therefore, since they were ignoring both programming methodologies and database methodologies, inventing the wheel from scratch, those new methodologies have progressed very slowly. And with assistance from a similar crowd, without sound academic basis.
Programs today have hundreds of methods that are not used. We now have programs to detect that. Whereas with the mature methodologies, we prevent that. Thin client was not a goal to be achieved, we had a science that produced it. We now have programs to detect "dirty" data and to "clean" it. Whereas in the upper end of the database market, we simply do not allow "dirty" data into the database in the first place.
I accept that you see database design as a series of re-factorings, I understand what you mean. To me it is a science (methodology, standards) that eliminates ever having to re-factor. Even the acceptance of re-factoring is loud signal that the older programming methodologies are unknown; that the current OO methodologies are immature. The danger, what makes it annoying to work with OO people, is that the methodology itself fosters a confidence in the One Hammer mentality, and when the code breaks, they have not one leg to stand on; when the system breaks, the whole system breaks, it is not one small piece that can be repaired or replaced.
Take Scott Ambler and Agile. Ambler spend 20 years publicly and vociferously arguing with the giants of the database industry, against Normalisation. Now he has Agile, which although immature, has promise. But the secret behind it it Normalisation. He has switched tracks. And because of his past wars, he cannot come out and declare that honestly, and give others due credit, so it remains a secret, and you are left to figure out Agile without its fundaments being declared.
Prognosis
That is why I say, given the evidenced small progress in the OO world over the last 20 years; the 20 or so OO methodologies that have failed; the shallowness of the approach, it is highly unlikely that the current OO methodologies will achieve the maturity and acceptance of the (singular) database design methodology. It will take at least another 10 years, more likely 20, and it will be over taken by some replacement for OO.
For it to be a possibility two things need to happen:
The OO proponents need formal tertiary education. A good grounding in the science of programming. Sure, anyone can do anything, but to do great things, we need a great grounding. That will lead to the understanding that re-factoring is not necessary, that it can be eliminated by science.
They need to break their denial of other programming methodologies and standards. That will open the door to either building OO on top of that, or taking the fundaments of that and merging it into OO. That will lead to a solid and complete OO methodology.
Real World OO
Obviously I speak from experience. On our large projects we use the mature analysis and design methodologies, one for database and another for function. When we get to the code-cutting stage, we let the OO team use whatever they like, for their objects only, which usually means UML. No problems with architecture or structure or performance or bloatware or One Hammer or hundreds of unused objects, because all that was taken care of outside OO. And later, during UAT, no problems with finding the source of bugs or making the required changes quickly, because the entire structure, has documented structure; the blocks can be changed.
I think this is an interesting question, because it presumes that Codd's Normal Forms are actually the definition of "correct" design. Not trying to start a flame war with that statement, but I guess my point is that there are very good reasons that many DB's aren't fully normalized (e.g. join performance) leads me to think that the real-world equivalent of normalization in OO space is probably design patterns or (as you said) SOLID. In both cases you're talking about idealized guidelines that have to be applied with a suitably critical eye, rather than slavishly followed as dogma.
Not only do I fully agree with Paul, but I will go a step further.
Models are just that - only models. The Normalization models used by Relational Databases are only one approach to storing and managing data. In fact, note that while RDBMS's are common for Data Manipulation operations (the standard CRUD), we have now evolved the DataWarehouse for consolidation, analysis, and reporting. And it most definitely does NOT adhere to the normalization models found in DML land.
Now we also have Google with their BigTable architecture, and Apache with Hadoop. These newer modeling systems reflect a change in the landscape, driven by the idea of the DISTRIBUTED database. Normalization need not apply for this club either.
We can apply a successful model ony to the point at which it becomes not-so-successful, or is supplanted by an model which better suits the needs of the designer. Note the many ways we humans have modelled our universe through physics/Astronomy what have you. Modelling attmpts to describe a system in discreet terms, but as the system, or the needs of the system change, so must the model.
OOP is and has been a very, very successfulk way to model computer applications. However, the needs of the application designer are different from thos eof Database designers. MOST of the time, there is a point at which the designer of an application must consider that his program will be interacted with by humans. Unlike the database designer, whose work will (mostly) be expected to interact with other code, the programmer's job is to take the machine and make it accessible to a much more random human-being. This art does not map quite so well to such standards like normalization.
All that said, n-tier, MVC, MVVC, and other paradims DO establish some guidelines. But in the end, the problem-space of application design is usually not as easy to fit into such discrete modelling steps as a relational databse.
Wow. Apologies for the length. If this is a breach of ettiquette here, do let me know . . .
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 4 years ago.
Improve this question
Having recently worked with a bunch of people (from two different companies) right out of school or with 1-2 years experience, I was initially quite impressed with their knowledge of the various industry buzz words and design patterns etc. Furthermore they each had a good understanding on OO design principle and use of interface.
To cut a long story short…. In just a few days of working with them I found that things were not as they appeared.
Let me define some terms I’ll use here
Knowledge – Something you learn either in school or book or on the Internet etc.
Experience – The amount of time you’ve been doing something
Skill – Only gained through experience. That is acquiring skill (over time) and knowing how to apply the knowledge you have
What I found was that even though they knew this stuff, they really didn’t know how to apply this knowledge. You’d have all these patterns waving in your face but any code they had to write of their own accord had basic flaws with it. They could tell you the virtues of a certain design pattern and could come up with somewhat of an implementation but could not recognize basic flaws in the design.
Of course I had my fair share of the “One who knows not that he knows not –Confucius”.
Each night I’d spend a lot of time re-iterating everything that was said during the day trying to understand who was saying what and why, trying to figure out what I could do by way of examples during training or code review. But frankly I was quite puzzled.
After about 2-3 weeks I started to figure it out.
Anyway, the questions first
1. Have you experience this sort of thing?
2. How did you (or do you) tackle this?
My conclusion was that either schools are doing a bad job or Google is their friend and they’re getting all this “knowledge” and think they know.
But I feel
In order to be able to recognize and appreciate good design one MUST write code that is well,… not so well designed. Struggle with it and then fix it to know the pain and therefore recognize good and bad design and appreciate it
Practice and Experience – you just can’t beat that. There is so much that experience (and the quality of experience) brings to the table that you just can’t match it with just knowledge or a little bit of experience.
Some other things I experienced:
“Why is this an interface and not a base class” – you’ll get all kinds of answers but none of them is the right reason.
Why this design pattern and not that, or forget design patterns for a minute and just design (they’re utterly lost – that’s when you see their real design coding skills)
Over engineering – don’t recognize it and can’t appreciate they it could be a maintenance nightmare as the system grows. I found this to be a big issue. It's as if everything has the potential to change. A simple process of sending an email has 3 classes in addition to the various classes the in the .NET framework you'd use to send an email.
Using all the new features in the framework or language just because (I’ve even seen this in some of Microsoft’s source code for a certain framework for which source code is available)
So 10 years from now, everyone writing code is writing it using all the fancy framework or language features using all the possible design patterns, such that “legacy” code is well written and well designed. Or is it? What do you think?
Does anyone else feel that 10 years from now we’ll just be shifting through a different kind of muck. Muck that’s scattered about in a dozen more code files then it used to be because now we’ve got classes and so called loosely coupled code but it’s just a different kind of mess and in fact harder to clean up?
Interesting deliberations. I have always felt that with time we are over engineering our systems with all the patterns flying around. An extra layer of abstraction means more failure in understanding in future. My personal approach is to keep things simple and only introduce complexity if it is required. Decouple if decoupling is required. Many of the design requirements do flow in systems because we blindly put in requirements document that it should be maintainable, reliable and all *able. It's also necessary to understand the degree in which we want these *ables and more importantly how they impact our budget and business values both in shorter and longer term.
One important aspect is always to keep a very tight focus on business requirements, at every stage, both in terms of functionality and budget.
I completely agree that the newer breed of developers appear to be very knowledgeable when it comes to design patterns and the latest buzzwords like hibernate, jason, nant, ajax etc. In the other hand I have found that even the best among them, those who can be considered star programmers appear to have limited understanding and knowledge of what is really happening under the hood.
I had a several conversations in the past with young guns who were viewing spring as a major innovation trying to convince them that what this framework is providing us through reflection consist the evolution of things like IDL, type libraries, COM and CORBA.
When it comes to design patterns and the terminology introduced by the gang of four, we all know that their proposed architectures have been used for decades before and a senior developer was using them almost intuitively without knowing the formal differences of a regular factory versus an abstract. There is no doubt of course that the formalization that was introduced by the movement of DP was beneficial for the industry although the recognition and successful implementation of patterns still (and probably always) rely in the experience and talent of the developer since this process is impossible to become a purely mechanical and deterministic.
An additional point I have to make regarding newcomers to the field of SD is their inclination to spread their skill set very horizontally, trying to cover as many technologies possible as opposed to deeply concentrate in a specific domain and master it.
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.
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.