10

Whenever I was required to build a project, I always managed to build it, not beforehand devising a plan or design, but after first writing a class that was needed, fleshing out the entire project, building from the bottom-up. Now I know this is not the proper way to create software, but it is not easy for me to wrap my head around what is called Objected Oriented Analysis and Design. I can more easily understand top-down procedural design, for it consists in merely breaking down tasks into sub-tasks, things which have their counterpart in code, functions. But Object Oriented Analysis and Design I cannot easily understand, for I do not understand how one can know what classes they will need and how they will interact, unless they know how they will code them.

For once we introduce the concept of classes and objects into the design process, we can no longer design top-down, because we are no longer breaking down our problems into those things which can be implemented as procedures. Instead, according to what I have read on the subject, we must determine what classes are needed, and create various artifacts in Unified Modelling Language, which we can then use when we implement the software. But this kind of design process I do not understand. For how does one know which classes they will need, and how they will interact, unless they have already conceived of the whole system?

This then is my problem. I do not understand how to design an Object-Oriented System, although I do understand the concepts of Object Oriented Programming, and can use those concepts in any Object Oriented Programming language that I know. Therefore I need someone to explain to me what simple process I can use to design Objected Oriented Systems in a way that makes sense to me.

  • 8
    "Now I know this is not the proper way to create software" - who told you this? It seems somehow you fall into the popular trap of believing "design is something what you do before coding, maybe by drawing fancy UML diagrams". To cure you from this misconception, I recommend to start with "Code as Design" by Jack Reeves. – Doc Brown Jun 21 '17 at 5:27
  • 2
    Possible duplicate of Is is preferable to design top down or bottom up? – Doc Brown Jun 21 '17 at 5:33
  • @DocBrown. Don't you think that design while coding is what makes our job so artisanal? I can not imagine other engineeries working alike. Imagine an architect pilling bricks and mortar and designing the building/bridge on the way. – Laiv Jun 21 '17 at 6:07
  • 5
    @Laiv: "coding" is part of what in other engineer disciplines is called design. In house building, the step from design to the end product is done using pilling bricks and mortar. In programming, this step is done by the compiler when translating the design (=program) into the end product (=executable binary). And that is not a new wisdom. Reeves essays are 25 years old. – Doc Brown Jun 21 '17 at 6:39
  • @DocBrown, is developer.* no longer curated? The subscribe button is broken for example. – radarbob Jun 28 '17 at 18:57
20

Top down waterfall style OOAD does not ensure that the code you write is object oriented at all. I have seen mountains of strictly OOAD produced code that proves it. If OO is confusing you, don't look here for help. You wont find it. OO does NOT require you to design top down.

If diving into a class is how you like to code, so be it. Let me tell you a hint. Procrastinate.

It's amazing how easy it is to design classes by writing code that uses them even when they don't exist yet. Forget procedure. Forget structure. Just get yourself a nice consistent level of abstraction going and stick with it. Don't give into temptation and mix extra details into it. Anything that takes you out of the current abstraction can go be done in some method that might be on some other object that somehow knows whatever it needs to know. Don't build anything you can just ask to be handed to you.

Learn to write like that and you'll find you're doing OO without even trying very hard. This forces you to look at your objects from the point of view of how they are used (their interface) and which objects know about which other objects. Guess what a UML diagrams main two points are?

If you can get into that mode of thinking then what's left is architecture. We're all still figuring that out. From MVC to clean architecture to domain driven design. Study them and play. Use what works. If you find something 100% reliable come back and let me know. Been doing this for decades and I'm still looking.

  • 2
    Or you find yourself not doing OO and yet everything "somehow" works out fine anyway... – Derek Elkins Jun 21 '17 at 5:07
  • 2
    "It's amazing how easy it is to design classes by writing code that uses them even when they don't exist yet" - I call this top-down design, but it seems that I'm wrong. What is top-down design and what is this thing I called so? Is it programming to an interface? – Piovezan Jun 23 '17 at 23:51
  • It's not simply top down. You also have to be willing to not build things you can just ask for by accepting parameters. – candied_orange Jun 24 '17 at 0:50
  • @Piovezan you can do this even when the interface doesn't exist yet. Just ignore your compiler for a bit. Later, you'll make it exist. – candied_orange Jun 28 '17 at 11:13
  • @CandiedOrange "You also have to be willing to not build things you can just ask for by accepting parameters." - I'm not sure I understand, could you please clarify/provide a short example (or counter-example for that matter)? – Piovezan Jun 28 '17 at 15:58
4

You claim to be able to use object-oriented techniques in your code, so by that you do know how to design an object-oriented system already, I believe your problem is more of a matter of when, not whether or not you can. You seem comfortable with object-oriented design in a short-term iterative way, instead of a long-term planning way.

When first developing a project it can be very difficult to plan and design, that's when agile development is favoured over waterfall development, as the grand scope of a waterfall plan will often not capture all of the complexities of a software project.

You assert that developing on-the-fly without an "initial plan" is:

"... not the proper way to create software ..."

If your problem is that your initial plan is not detailed enough, take a little more time to explain your first thoughts. What is the first part of the program you plan to write? What is it going to need? Perhaps don't even think of what objects to start with, instead think of what features and plan from there.

If your problem is that you are not confident in your documenting / design / UML skills, practice by documenting an existing project.

Personally I would recommend to not worry about your designs being perfectly object-oriented, most systems are not 100% object-oriented. The goal is to create a better understanding and visualisation of the system, not perfect abstraction. Object-orientation is not the silver bullet, it's just another tool on the belt.

  • I also wanted to mention, though a bit off-topic for the answer... Your plans don't need to be very big! Sometimes a plan is just a matter of "I want to run it and it does a thing." That's good enough, if that's really all it's going to do. – Erdrik Ironrose Jun 21 '17 at 9:33
2

OOAD is a utopia. By that I don't mean that it is the best approach, I mean that it is never truly achievable in my humble opinion. In my experience, something always changes, whether it be requirements or specifics, or even a dependency conflict that forces you to replace a dependency entirely. Whether it be because I learned this way or because it is what comes most naturally for me, my ideas for design come most readily as I am writing code. If I'm about to code and I don't have a clear idea of how I'll structure the code, I'll make a point to dedicate time towards truly understanding the problem first, though more often than not, I see the necessity for a class and I'll make it.

My advice would be that the best thing you can do for yourself is code using facades, providing a simple interface for input and output, and hope that the inputs and outputs don't change often. Though even if they do, know that it isn't a design problem so much as it is a specifications problem (change in necessity/operation/functionality). This will make your program somewhat resistant to problems resonating within your program towards those who call your program or section of code and vice versa.

For what concerns designing an object oriented system, something should be said for trying to make everything object-oriented when it shouldn't be. That is a common mistake among OOP programming languages like C# and Java is to try to treat everything as an object, which often results in creating a single instance of a class to perform what would otherwise be static methods that don't change state whatsoever. That said, of course you should use OOP design where applicable, though don't feel like you're doing it wrong when it feels more natural to write a static method. It isn't always the wrong instinct.

You should consider using a class when you answer yes to any of the following questions:

  • Do I have a group of information that pertain to the same concept (i.e. first name, last name, address)?
  • Do I need to perform an operation requiring several pieces of information (i.e. calculatePrice(basePrice, quantity, tax))?
  • Do I have an else if with large code blocks performing slightly different operations with the same or similar information (i.e. if(type == "cat") { meow(name); } else if (type == "dog") { bark(name); } ==> animal.speak())
  • Do I have an existing class which performs more than one specific task and is growing a bit too large?

After a while, it will become second nature to create classes. Don't be afraid to use them if your code falls into one of the cases above. I hope that helps!

2

I think that the points made by Doc Brown in the comments deserve a lot more visibility than a comment since he's absolutely right:

"Now I know this is not the proper way to create software" - who told you this? It seems somehow you fall into the popular trap of believing "design is something what you do before coding, maybe by drawing fancy UML diagrams". To cure you from this misconception, I recommend to start with "Code as Design" by Jack Reeves. – Doc Brown Jun 21 at 5:27

@Laiv: "coding" is part of what in other engineer disciplines is called design. In house building, the step from design to the end product is done using pilling bricks and mortar. In programming, this step is done by the compiler when translating the design (=program) into the end product (=executable binary). And that is not a new wisdom. Reeves essays are 25 years old. – Doc Brown Jun 21 at 6:39

This same sentiment is also echoed in other places. Consider Glenn Vanderburg's talks on "Real Software Engineering", and to some extent his "Craft, Engineering, and the Essence of Programming" and "Craft and Software Engineering" talks. Also consider the WhatIsSoftwareDesign and TheSourceCodeIsTheDesign pages/discussions on the C2 wiki.

The concept of the code being the design is not specific to any paradigm. It can be applied equally to object-oriented, functional, procedural, logic, or anything else. The underlying idea is the same - the design is the source code itself. The act of construction is the process by which the source code (the design) is turned into a usable thing by an interpreter or compiler.

In a complex system, there is likely to be some level up architectural design - identifying subsystems, components, modules, services and allocating requirements to them before you start writing code. You may use UML as a way to create, document, and aid in discussions around this architectural design. Consider the idea of UML Modes that Martin Fowler discusses, particularly UML as a Sketch and UML as Notes. Also consider some ideas from Agile Modeling - Initial Architecture Modeling, Iteration Modeling, and Just Barely Good Enough models.

All of this means that the right way to build software is not to flesh out the entire project. It's to spend just enough time understanding the most critical (at the current point in time) requirements, identifying technical dependencies and trade-offs between requirements, and then taking advantage of the fact that software is soft. Also recognize that the cost of taking your design and producing something is incredibly low (especially compared to taking a design and producing something in many other engineering disciplines). So iterate on your design (coding) activities and take advantage of how easy and cheap it is to progressively build or modify what you have done.

1

OOAD is about identifying entities and modeling real life objects or concepts to a degree of abstraction. You will perceive it as being easier if instead of writing classes yoy write interfaces at first, since you don't really have to implement them yet, yet the code compiles.

OOAD doesn't exclude the posibility of thinking in the system as big modules. You can still do that. Each module exists to satisfy a set of user stories (use cases). Such user stories needs classes that collaborate to fulfill them.

One key difference between procedural an OO approaches is that usually procedural thinking maps requirements to screens, whereas OOD has a tendency to think of what happens under the hood leaving the front end to be made by another person or in a non-OO fashion.

There's a technique in Extreme Programming called CRC Cards. CRC stands for "class-responsibilities-collaborators".

Basically you identify evident classes and assign a card to each one. Say, the class Invoice has its own card.

For every card-holding class you write what the responsabilities of that class would be, for example "calculates a grand total".

Also for every card-holding class, you write what other classes that class has to ask something for in order to fulfill its own responsabilities. Here you may discover Invoice needs the collaboration of InvoiceDetail or even discover that such a class is needed in the first place.

You may discover that some responsabilities you thought belonged to Invoce, really belong to one of its collaborators.

After the exercise, every card becomes a class, every responsability becomes a method and every collaboration relationship may become a composition, an agregation or a mere call.

That excercise can (and should) be done in a group, where even business people particpate.

You can learn more about this technique in these links:

http://en.wikipedia.org/wiki/Class-responsibility-collaboration_card

http://www.extremeprogramming.org/rules/crccards.html

Examples of CRC cards:

enter image description here

enter image description here

enter image description here

0

The primary challenge for us, as a community of software practitioners; more specifically object oriented design practitioners, is that of materializing all our problems/tasks into a programming couterpart. Be it tasks - represented as functions or be it actors of the tasks - represented as interfaces/classes [driving towards OOAD]. As we evolve our software designing habits, by continuously gaining knowledge about various methodologies/frameworks. Our point of view gets more and more refined towards clearly segregating the objects and which object would perform which function.

As for breaking down your problems into sub-problems with the presence of objects around, you can still conveniently do that, for YOU have the total control of which all objects you want to be present. You also have the convenience of imparting nature and purpose to your objects and interfaces. All you have to do is, visualize the problem statement and think of which purpose/functionality can be imparted on which object.

I will try to explain futher with the help of an example of the range of automobiles and I will highlight two different ways of visualizing the same object model.

Take an example of the automobile manufacturer who spans across various categories of automobiles: commercial vehicles, consumer cars(sedans, hatchback,station wagons) etc.

For the manufacturer to clearly have a separation of category and purpose, there are multiple ways with which they can create there classes.

Vehicle Manufacturer OOAD

  1. Based on the category(market sector) of vehicle: Heavy vehicle, consumer vehicle [sedan, hatchback, station-wagon etc.]

  2. Based on the engine capacity & driving manner: 800-1500 CC, >1500 CC etc.

Going by the best way in which the manufacturer can individually impart functions to objects belonging to each of these classifications, they can choose an appropriate underlying object design and build there model on top of it.

  • You start out ok, but then the last bit looks like the fallacy that OOD is about categorising things rather than grouping similar behaviours. – Pete Kirkham Jun 28 '17 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.