Two ways to design complex system: Top-down vs Bottom-up - java

I have a complex system to design.
I have two ways:
Top-down: I will design many interfaces and contracts. Afterwords, I will implement these interfaces, and write a prototype to verify the design.
Bottom-up: I will write code to make the system run. Afterwords, I will extract interfaces and contracts from solid code. The distilled interfaces and contracts is my design. It's rule "make it run, make it right".
What is better way? From my opinion, I will choose Bottom-up. Because Top-down is very difficult, no one can design many interfaces at high abstract level,at least it's hard for me. When I write solid implementation to verify the initial design, there are many unreasonable things which force me to re-design from scratch. While I use Bottom-up, I feel quite "safe", it can run at least.

As others have said, it's usually a mix. On a more practical level, the following approach usually helps:
Start by going ABSTRACT Top-Down. Namely, break the system/design into logical components to solve tasks. But don't design precise finalized interfaces for those components. Proceed recursively till some components you arrive at are of "implementation-possible" size (e.g. are the size of a single function/method/class)
Then, go through the resultant component list Bottom-Up, and start designing first draft of interfaces/contracts.
Then, go through the resultant component list Bottom-Up, and start implementing them. This will allow you to:
Have a working and testable code immediately (no need to wait for underlying components to be implemented to test)
You can synthesize the final version of interfaces/contracts for higher level components based on the needs of the already-completed lower level components.

Except in most trivial designs nothing is ever this simplistic. I find that most designs require a mixture of both methodologies to refine.

In my opinion, top-down design is more natural than bottom-up one. E.g.: when you are designing a system, primarly you define its functionality(design interfaces and contracts), then you specify the entities of the system, implement relations among them and so on... Certainly, top-down design is more difficult than bottom-up one, and it requires experienced developers.

I personally also prefer Bottom up - first because you always forget something when doing top-down and then have to fix that and second because at least in my case I get lots of good ideas for the complete system while designing the single components from bottom.
Greetings,
Lorenz

In the real world is nearly impossibile to use these simplistic methodologies to design systems. You usally have to use both of them in multiple iterations.
But this is a simplistic answer, too.

Related

Too many actors in LibGDX?

I'm programming my first game in LibGDX and part of the gameplay has a mixing logic between elements (similar to Doodle God or Little Alchemy). By reading and watching guides, I've attempted to design this logic using LibGDX classes Stage, Actor (for the elements) and Group(for organising elements), but then I realised I would need an actor for each element. Since I intend to have over 150 of them, creating a java class for each one really doesn't feel optimal. Neither do I know an efficient way to store all the logic so I can look for combinations with a single call (I don't want to write a million if statements in a method).
I would like to know if there's a simple and elegant way for doing that. Thanks in advance!
P.S.: The only differences between elements are their textures, the groups they go into and the elements they combine with.
There is indeed a pattern that is currently well used for doing what you expect. It's called entity-component-system (or ECS).
It requires a shift in thinking how to develop games, but it's worth it, especially for its modularity and reusability.
Wikipedia has a much detailed article about it.
And it's a good thing that libgdx has Ashley, their ECS implementation.
If you can, reuse Actors maybe?
If we talk about logic.
You can group logics and write a function for every group.
Don't use ifs, use switch and enums.
Maybe if you tell us more then we can come with something innovative.

Difference between Composability and Decomposability

I've been looking across the web for a simple explanation about the differences between the two.
I understand composition is "bottom-up" design while decomposition is "top-down" design.
However, aside from that - are there any further differences?
If a program implements the "composability" principle, does it necessarily also implement the "decomposability" principle, and vice-versa?
It's obvious how these two can lead to different designs, but all in all, it seems they represent exactly the same thing from different point of views.
Clarifications will be highly appreciated.
Cheers!
Some reference links:
YorkU
Blog about Modular Composability
Blog about Modular Decomposability
As the first link you've provided shows it, these two approaches are not incompatible. You just need to know when to use one or the other.
From my experience, top-down design is a good approach when you start designing, as you need to discover your system, understand the requirements and making something works quickly. As you add more and more features, specific responsibilities start to emerge and this is where decomposing your problem is required. This will prevent to duplicate code from one feature to another, and lower the efforts required to compose new ones.
Choosing between one approach or the other is just a matter of figuring out the right design decision to take at a proper time. If you feel that some aspects of a problem are still unclear, there is no reason to decompose it. Just wait until your module cries out for modularization (for example, having a hard time to understand what you wrote some days ago would be a good sign, same for duplicated code).
Is this answering your question ?

when and why do we need to divide a class into many classes?

I am an android beginner developer. Currently, I am developing an application. However, my class is quite large because there are many UI components (to handle onClick, onProgressBarChanged, etc.).
Most of my components are dynamic. So, I have method to create those components.
Now I split some methods for initializing UI components into another class.
At this point, I am trying to think/search for a good reason to split my class into several classes.
Advantage: maintainability, testability, reusability
Disadvantage: reduce runtime performance
I am not sure that there is any advantage or disadvantage that I have missed?
Furthermore, I will divide a class when I find an overlap method
I am not sure that there is another situation when a class must be divided.
First, if you've never looked into refactoring, then I would strongly encourage you to do so. Martin Fowler has some excellent resources to get you started. But, I'm getting slightly ahead of myself.
To begin with, you split out classes to maintain a clear delineation of responsibilities. You can think of the SOLID principle here - each class does one thing, and one thing very clearly.
If you notice that a method, let alone a class, is doing more than one thing, then that is a good time to stop and refactor - that is, take the code you have, and apply a particular, focused refactoring to it to improve readability and flow, while maintaining the same functionality. You're essentially looking for code smells - parts of the code that are suspect, not following a specific contract or methodology, or are legitimate anti-patterns - which are, themselves, practices that developers strive to avoid.
Programs that deal with UI (especially in Java) tend to be pretty verbose. What you should avoid doing is placing any conditional business logic in the UI layer, for ease of separability, testing and clarity. Make use of the Model-View-Controller pattern to understand and abstract away the necessary separations between the UI (Views), and the actual work that's needed to be done (Controllers), while maintaining some semblance of state (Models).
We use OOPs Concept in Android(core java) Application Development. If we split our one class in many class it gives a good sense of maintainability, re-usability, Security and Easy change in Coding during Development.
As for example:- Util class for Database handling, Network Class for Internet connection , Dialog class for different type dialog and so...
This way we can categories our coding and change or re use it any time. So it is good practice to follow the OOPS concept during Development.
Thanks

Coupling/Cohesion

Whilst there are many good examples on this forum that contain examples of coupling and cohesion, I am struggling to apply it to my code fully. I can identify parts in my code that may need changing. Would any Java experts be able to take a look at my code and explain to me what aspects are good and bad. I don't mind changing it myself at all. It's just that many people seem to disagree with each other and I'm finding it hard to actually understand what principles to follow...
First, I'd like to say that the primary reason you get such varying answers is that this really does become an art over time. Many of the opinions you get don't boil down to a hard fast rule or fact, more it comes down to general experience. After 10-20 years doing this, you start to remember what things you did that caused pain, and how you avoided doing them again. Many answers work for some problems, but it's the individual's experience that determines their opinion.
There is really only 1 really big thing I would change in your code. I would consider looking into what's called the Command Pattern. Information on this shouldn't be difficult to find either on the web or in the GoF book.
The primary idea is that each of your commands "add child", "add parent" become a separate class. The logic for a single command is enclosed in a single small class that is easy to test and modify. That class should then be "executed" to do the work from your main class. In this way, your main class only has to deal with command line parsing, and can lose most of it's knowledge of a FamilyTree. It just has to know what command line maps into which Command classes and kick them off.
That's my 2 cents.
I can recommend Alan's and James's book Design Patterns explained -- A new perspective on object-oriented design (ISBN-13: 978-0321247148):
It's a great book about has-a and is-a decissions, including cohesion and coupling in object-oriented design.
In short:
Cohesion in software engineering, as in real life, is how much the elements consisting a whole(in our case let's say a class) can be said that they actually belong together. Thus, it is a measure of how strongly related each piece of functionality expressed by the source code of a software module is.
One way of looking at cohesion in terms of OO is if the methods in the class are using any of the private attributes.
Now the discussion is bigger than this but High Cohesion (or the cohesion's best type - the functional cohesion) is when parts of a module are grouped because they all contribute to a single well-defined task of the module.
Coupling in simple words, is how much one component (again, imagine a class, although not necessarily) knows about the inner workings or inner elements of another one, i.e. how much knowledge it has of the other component.
Loose coupling is a method of interconnecting the components in a system or network so that those components, depend on each other to the least extent practically possible…
In long:
I wrote a blog post about this. It discusses all this in much detail, with examples etc. It also explains the benefits of why you should follow these principles. I think it could help...
Coupling defines the degree to which each component depends on other components in the system. Given two components A and B ,how much code in B must change if A changes.
Cohesion defines the measure of how coherent or strongly related the various functions of a single software component are.It refers to what the class does.
Low cohesion would mean that the class does a great variety of actions and is not focused on what it should do. High cohesion would then mean that the class is focused on what it should be doing, i.e. only methods relating to the intention of the class.
Note: Good APIs exhibit loose coupling and high cohesion.
One particularly abhorrent form of tight coupling that should always be avoided is having two components that depend on each other directly or indirectly, that is, a dependency cycle or circular dependency.
Detailed info in below link
http://softwarematerial.blogspot.sg/2015/12/coupling-and-cohesion.html

Splitting objects into their most fundamental parts

Not sure if the title captures what I'm trying to say here.
When designing in OO should I be splitting my objects up into their most specific areas - so if I have a factory object that deals with creating objects but later on i come across a way of creating objects for another purpose even though they may be the same objects is it worth creating a seperate fcatory or just add to the exsiting.
My biggest worry is bulking up classes with tons of stuff, or splitting objects and diluting my projects into a sea of classes.
Any help?
EDIT:
I guess on a side note/sub topic part of me wants to find out the level of granularity you should use in a program. Kind of, how low should you go?
My biggest worry is bulking up classes with tons of stuff, or
splitting objects and diluting my
projects into a sea of classes
This is a very valid point and in any even reasonably sized project, extremely difficult to get right up front especially because realistically, requirements themselves evolve over time in most cases.
This is where "Refactoring" come in. You design based on what you know at any given point and try not too make too many leaps of faith as to what you think the system MAY evolve to.
Given that you know what you are building right now, you design your classes trying to make the best possible use of OO concepts - eg encapsulation / polymorphism. This is itself, like others have noted as well, can be notoriously difficult to achieve and thats where experience, both in designing OO systems as well as knowledge of the domain can really come in handy.
Design based on what you know --> Build It --> Review it --> Refactor it --> Re-design --> and it goes on and on..
Finding the correct level of detail and responsibility is what makes OOP design so difficult. We can help you with a specific case but not with anything this general. If there were algorithms or strict methodologies of how to solve this, everyone could be an OOP designer.
A rule of thumb I like for deciding "is this getting too big now?" is "can I explain the purpose of it concisely?" If you start having to introduce caveats and lots of weasel words to explain the functions of a component of your design (be it class, member variable, method or whatever) it might be a good indicator that it's getting too complex and should be split up.
In your specific case, if you already have a factory object then the DRY Principle (Don't Repeat Yourself) would say that it's a bad idea to create another factory that does the same thing.
Is this an actual problem that you face? Or merely a fear about how your code might grow in the future?
If you are using the same type of object to solve drastically different problems then you may need to redesign the class to focus on seperation of concerns. If you need a more specific answer, you will need to provide an example of a type of class that would need this functionality.
I might have worded things badly in
the Q. I guess I wouldnt be repeating
myself its just more of a case of
where to put the code, it could be
added to an exsiting factory that
creates design objects for exporing
data to excel spreadsheets. On the
other hand I could see it could also
have its own factory for importing
excel data. Both factories would
produce the same objects but the inner
workings are completely different. –
If you aren't doing or plan on doing any class abstraction (subclassing or using interfaces) you may not need to use the factory pattern at all. The factory pattern is generally best suited for supplying objects of a base class type or that implement a specific interface.
Both
factories would produce the same
objects but the inner workings are
completely different.
Not sure if I've understood you correctly, but this sounds like a candidate for the AbstractFactory pattern.

Categories