Is it arbitrarily flexible to make the code dirty?

Is the rigidity of intuitive interfaces that flexible code should be ugly? I will use Java and Perl as relevant examples.

Clarification: this is not the code that is confused, makes it flexible; but this code is flexible, makes it dirty.

Clarification: "flexibility" almost has a different meaning in search code versus old code. Perhaps raw flexibility and compatible flexibility? I'm talking about "raw flexibility" - thanks to Mario Ortegon

Java

Java pays great attention to compatibility: the content of the language and standard libraries is saturated with the OO design and even has a widely used keyword interface; The JVM and the language itself have characteristics of external behavior. Sun has a history of clear and open specifications (such as NFS).

Developing a clear interface that works well is very difficult to do, but when done correctly, the result can be very clear. The specification (including the design of OO) is rigid in nature - any flexibility that it has is severely limited by the specification.

The result is that if you correctly predicted the required degrees of freedom, the design has great clarity and accuracy - it will actually serve as a guide for the right questions to ask, and give you useful conditions that you might think about the problem.

Perl

One Perl spirit is "there is more than one way to do this." and the syntax language itself has changed significantly over the years (including incompatible changes). Like Java, this relationship extends to programs written in this language.

Although you can write Perl to clean up interfaces, it does not apply and often fails. This may mean “writing only” code, but if you understand it, you can change it arbitrarily. That is, it is ugly, but flexible - perhaps my change in ugliness needs to be changed?

Apparently, mjd said of a higher order Perl, which he could not write with a test development, because he lacked the necessary flexibility. Hopefully I won’t put words into his mouth here, but I think the same applies to interfaces and specifications (because this is what TDD provides).

It seems to me that Java code tends to be neat but tough; and Perl code is dirty but flexible. Support Java preliminary design; and Perl promotes rapid prototyping.

In my code (Java), I am confronted with the choice between neat and flexible. For example, I compared the Visitor template with one large if cascading function.

The latter is ugly, but in many cases it is easier to add parameters to the calls of the recursive method (this is only a problem if you need such a degree of flexibility (which I find in search prototyping).

Explanation: The visitor template reorganizes the cascading one — if the method overrides, by defining and calling these methods, one class for each, so the added argument must be added to all these methods and all calls from them, in all these classes. I coded these projects and calculated how many places the arguments added: 9 places for visitors (in different files); 3 places for cascading-ifs (all in one file). The cascading-ifs solution is much easier to modify, although it is ugly.

This question is not about Java and Perl - I just use them as illustrative examples to make the question more specific and specific, and hopefully easier to consider.

Is arbitrarily flexible code necessarily messy?

+6
design
source share
11 answers

It often works the other way around

I mainly work in C # and Python, so this may explain my difference in experience.

Code that is clean, elegant and simple, often more reusable and flexible than code that is contrived and ugly. This is easier to understand and therefore easier to adapt.

When I compare C # code (comparable to java) and Python code, I often find python code cleaner and more elegant, there is less rigid “ceremony” around type declaration, etc. This makes the code cleaner as well as more flexible.

However, you can make the code more flexible and less understandable. If you make the code flexible by explicitly adding extension points, it will often become less elegant.


@ 13ren: Great point for "invisible extension points", not only in Python, but in most dynamically typed languages. Languages ​​that use duck printing automatically assume that you are "programming an interface, not an implementation." This makes the code flexible and extensible. The problem is that you no longer define your interfaces, everything is automatically an interface. In C # and Java, you must do this manually, in many cases this is a “ceremony” and it gets in the way. In many other cases, the power to define your interface explicitly gives the developer strength.

+8
source share

No, I do not think so. I think this is very subjective, but I do not agree with your examples. You wrote:

For example, I compared a visitor pattern against one big cascading if function. The latter is ugly, but it’s many times easier to add parameters to the recursive method (this is only a problem if you need such a degree of flexibility that I find that I am looking for prototyping.)

However, I think you could make the "cascade ifs" go away using polymorphism. For example:

http://googletesting.blogspot.com/2008/12/by-miko-hevery-google-tech-talks.html

You say cascading ifs are more flexible, if I understand you correctly, I disagree. They may be more flexible. I doubt it.

How flexible is dirty code? Is the spaghetti code very easy to change without the fear of "I broke something." I rarely worry about whether another implementation of the interface will violate existing code, as far as I am concerned about breaking the messy spaghetti code with minor changes.

In addition, the point of all this is flexibility. It's not just about just using all of these patterns and polymorphism, because it's "neat." The idea is to be more flexible and reusable. I think clarity is a side effect of this.

Of course, there may be several cases where just adding an extra “if” is easier , but I would not say that it is “flexible”. Perhaps we use various "flexibility".

+5
source share

Hmm, hard question :-)

I think flexible code can be much simpler and cleaner than specialized code, but it takes a lot of thinking and practice. I would say this:

  • specialized code is easy to run and harder to keep clean when requirements change.
  • flexible code is harder to structure clean at the beginning and in the correct order, then it is easier to accept new requirements because of the flexibility
+3
source share

As a rule, clean code is easier to bend as you wish. It is possible to create a simple and flexible interface.

Your mention of HOP helps highlight one of the easiest ways to provide tremendous flexibility to your APIs - to provide the ability to pass a link to a function (or whatever you call it in your chosen language).

The Perl collation function is a great example of this. Pass the ref code and list to get a sorted list. The ref code works with the localized variables $ a and $ b. If the code returns 1, $ a comes after $ b, returns 0 to establish equivalence, and -1 to put $ b in front of $ a.

Where does the power of this approach come from? It works so well because it encapsulates a choice . The idea behind the Visitor template is the same. Unfortunately. Java is such a detailed language that it costs more to implement and support than a bunch of if else if else if crud.

Strength, flexibility and simplicity are the result of good design. It is possible to create inelegant shit in any language (or any design environment).

+3
source share

I don’t think that rapid prototyping means more flexible code. I am sure that it is more flexible from the very beginning, but as the application grows, it becomes more and more difficult. Theoretically, the use of interfaces simplifies the separation of unrelated parts.

At the end of the day, it all depends on the design.

Say there is a curve. If the application is complex, a preliminary design is necessary in order to add new features in a timely manner. If the application is simple, then it is better to use something more flexible.

+2
source share

If you think about flexibility early on in your design, you run the risk of not understanding what difficulties you will encounter. One of the tips for filling out the code is to write a modular reusable component when you re-implement the same thing for the third time.

Flexibility is complicated. That's what refactoring is! Improve your code by adding features to it. Or you can simply add features as you go and end up with a bunch of ugly code. But maybe you need an ugly path so that you can gather experience and an idea on how to improve the flexibility and convenience of service.

+2
source share

From what I saw, LISP is about as flexible as the language can get. But it becomes mysterious more than dirty. Endless lists of lists are powerful and flexible, but repeating the template can lead to confusion with everything that looks the same.

+2
source share

I think one problem is the number of options available. The “design of everyday things” suggests that usability is enhanced by having multiple and clear choices (called “actions”).

By limiting the options available, the specification increases usability for the intended purpose and use. But this inevitably reduces flexibility in other unforeseen ways. Each hook available for arbitrary flexibility adds a choice that makes it more general, but less useful for specific tasks.

Several options → neat but tough.

Many options → dirty but flexible.

+1
source share

I think that you have all this in the opposite direction.

Clean, well modular code is as flexible as it is. Look at the number of libs available for java. Libraries that are used very carefully. They solve one problem, and they solve it well.

This gives the developer the opportunity to use the flexibility to decide what he needs and choose the libraries necessary to complete the task.

A single lib is flexible in the sense that you can use it in many different places.

Sorry, your big Blob of Mud if statements aren't flexible at all. He is difficultly connected to all that he calls. Do you want to use it elsewhere? Sorry, I can’t do this without changing the code.

What you really see is: given that the design, implementation, and architecture of the code are flexible in the sense of "everyone can change it at will, regardless of whether they know anything about the design results in ugly code. Which soon so tough and frozen that you can throw his way, and he won’t even go to the toilet, because he is so hard.

+1
source share

I think one problem is the number of options available. The “design of everyday things” suggests that usability is enhanced by having multiple and clear choices (called “actions”).

By limiting the options available, the specification increases usability for the intended purpose and use. But this inevitably reduces the flexibility of other, unforeseen ways.

OK, I think Doet a little back. With an example of a door push plate, the door already opens in one direction. The idea of ​​accessibility is to make it clear how it opens. Constraint comes first, and clarity comes next. A restriction has more features (I believe) with security and security. (Security, because every time the door opens, we expect it to oscillate and be protected, because it can be strengthened in the chosen direction to prevent entry.)

I really don’t think we are restricting the choice so that we know how to open the door, because we can make them swing if we want. Thus, after the limits have been set, the pressure plate makes it clear what you should do on your side of the door.

+1
source share

Flexibility, in my opinion, is best illustrated by the low link / high cohesion paradigm. Good flexible code is as streamlined and simple as possible. You know you're good at refactoring when you reduce clutter and increase simplicity.

+1
source share

All Articles