2015. június 18., csütörtök

Abstract thinking

Abstract thinking
As an Architect, abstract thinking is inevitable. That being the case, What principles to use during the phase of abstract thinking in a project, Techniques to grasp the abstracteness, identify the abstractness, developing concepts and ways to test if the quality of abstract thinking is good?





My 2 cents...

You are not born with abstract thinking, you learn it as you learn your language, then logical thinking, finding similarities, separate relevant attributes from the irrelevant ones.
You can apply this technique to programming. First you see tasks, but as you solve many of them, perhaps in various environments, languages and requirements, similarities emerge. You start "feeling", then seeing a model behind the processes. It takes time which can be boosted by analyzing high quality codes, reading good books (like Design Patterns), but the most you learn from refactoring your own code. Later, you do most of the refactor in your head, before typing any code. You may also like this: http://hajnalvilag.blogspot.hu/2014/10/coping-with-infinity-digitization.html

The picture that always helps me is a gang of dwarves (that is, your classes/components). They are happy when they have only one task to do (single responsibility), and a very few commands to deal with (narrow API). They don't want others to talk into how they work, neither to do different things. Split your task among this gang, the happier they are, the better your design is. At first, it is very likely to be weak, but will improve on each task you do. Too much talk means you should move the boundaries in the responsibility map; too complex code means you may split it to multiple dwarves.

Avoid duplicates, always consider how much these dwarves must "know" about each other. For example, instead of setting some parameters directly from outside in a service, consider offering predefined "work modes" from which the user component can choose. It is an extra cost in the beginning, but a great gain when you have to extend/refactor the service.

A good design makes you asking good questions before coding, contains segments that are not required right now but would be nice improvements, which also prepares you for many of the late change requests.





Andrea Baruzzo
...
I think that the term abstraction can have a wider meaning, that of abstract data type (in the compur science speaking) or that of the concepts of a specific problem domain.

We need to clarify the acceptation of the term before to start discussion.



Krishnan Ramanujam
Agree with Andrea. Thanks..




Nice try, Krishnan, but you are the asker, you should decide on which level you talk. The answer is 42, but what was the question? :-)

By the way, this is again a general/special difference: the "abstract" term is in general a way how we handle similarities and differences, then a specialization is how we translate this concept to programming terms, and finally, to actual programming construct in a language. If I translate this previous sentence to system design, the process is the same: "ideas" -> "abstract programming models" (like UMLs, charts, etc) -> "language constructs" (classes, interfaces, etc).



Krishnan Ramanujam
Say in a domain, we envision a possibility that can solve a problem in that domain. If we are given a blank slate, what are the questions to ask that will help us develop relevant concepts, what to consider so that a concept is developed rather than a specialized solution is developed even in the first pass of developing something concrete. Thanks..




Well, that is related to the "abstract" approach, I guess. And if there was a silver bullet, everyone would use it. Sorry, there is none (yet... on the other screen I am watching my own MetaEditor, trying to find out what is the exact, working definition of the meta components like Type, Attribute, etc., and that's VERY frustrating so makes me procrastinate like chatting here :-) )

So for now, the answer is not clear. You "should" focus on creating narrow APIs and independent components - but you will surely fail creating them by just mere guessing.

If you have a blank slate and low courage, then
  • 0: write a document that describes your system WITHOUT considering existing tools and solutions: why do you make it at all, what are the services you provide, what are the problems with providing them (speed, performance, etc), how do you plan to cope with them,
  • 1: check what others do on the field, and steal anything that looks usable,
  • 2: check against your concept, what is missing, what is too much in what you have stolen,
  • 3: hack together an ugly but fast first implementation,
  • 4: check it again and steal anything that looks usable,
  • 5: create a better implementation (cleaner structure, more details),
  • 6: goto 4 or 1, repeat.
In this way, you will either go bankrupt, because you have no time and budget to finish the system, or create an acceptable solution to your stakeholder, with which none of the parties are fully satisfied. Sorry, no silver bullet, almost all development project end in this state by the way, so don't be ashamed.

But you learn, and the process gets faster on each iteration. Watch the elder guys playing the same game, learn from their approach, success and mistakes, and let them fail until nobody else stands in front of you and you have to put your own bet on the table.

Good luck! :-)