Hot answers tagged

159

Test No, seriously, test. I've been coding for over 20 years and I still don't trust myself to write a loop correctly the first time. I write and run tests that prove it works before I suspect it works. Test each side of every boundary condition. For example a rightIndex of 0 should do what? How about -1? Keep it simple If you can't see what it does at ...


151

In such cases, it is best to use the type system of your language to help you with proper initialization. How can we prevent a FooManager from being used without being initialized? By preventing a FooManager from being created without the necessary information to properly initialize it. In particular, all initialization is the responsibility of the ...


73

The most effective and helpful way to prevent clients from "misusing" an object is by making it impossible. The simplest solution is to merge Initialize with the constructor. That way the object will never be available for the client in the the uninitialized state so the error is not possible. In case you cannot do the initialization in the constructor ...


60

When programming it is useful to think of: pre-conditions post-conditions variants and invariants (of loops or types) and when exploring uncharted territory (such as juggling with indices) it can be very, very, useful to not just think about those but actually make them explicit in the code with assertions. Let's take your original code: /** * Inserts ...


39

I would normally just check for intiialisation and throw (say) an IllegalStateException if you try and use it whilst not initialised. However, if you want to be compile-time safe (and that is laudable and preferable), why not treat the initialisation as a factory method returning a constructed and initialised object e.g. ComponentBuilder builder = new ...


36

Neither. Comments should not describe what code does (at the same level of abstraction as the code itself), but only why it does something Don't take this too literally, this is a guideline, if you write a short summary what a longer piece of code will do, that may be acceptable. However, comments describing obvious things like "this is an iteration" should ...


28

The comments you write are fine for demonstration code when teaching a new language for beginners. They're the equivalent of "See Jane run. Run, Jane, run!" But in every other settings they're not appropriate. Every habitual programmer would just be puzzled, thinking "Huh? Why are you telling me this when it's already utterly obvious what's going on? Is ...


22

Use unit testing/TDD If you really need to access sequences through a for loop, you can avoid the mistakes through unit testing, and especially test driven development. Imagine you need to implement a method which takes the values which are superior to zero, in reverse order. What test cases could you think of? A sequence contains one value which is ...


18

The main effect that language design has on "clean code" is at the syntactic level. Languages with a lot of shorthands and obscure operators (Perl/APL) lend themselves to "dirty" code, whereas languages with a smaller set of elements (say, Python) lend themselves to cleaner code. Semantics, however, are a very different animal. There is no way to enforce ...


16

Almost all Unix computers use twos-complement for integers, and in twos-complement -1 is always "all bits 1" regardless of the word size. If you want the largest possible exit code regardless of the size of the program's exit status, using -1 and letting the library truncate it conveniently does the trick. That's useful because when scripts or programs have ...


12

I'm going to break a little bit from the other answers and disagree: it's impossible to answer this without knowing what language you're working in. Whether or not this is a worthwhile plan, and the right sort of "warning" to give your users depends entirely on the mechanisms that your language provides and the conventions other developers of that language ...


11

I agree with other people who say test your code. However, it's also nice to get it right in the first place. I have a tendency to get boundary conditions wrong in many cases, so I've developed mental tricks to prevent such problems. With a 0-indexed array, your normal conditions are going to be: for (int i = 0; i < length; i++) or for (int i = ...


9

I got too frustrated because of the lack of correct computing model in my head. Is a very interesting point to this question and it generated this comment:- There is only one way: understand your problem better. But that is as general as your question is. – Thomas Junk ...and Thomas is right. Not having a clear intent for a function should be a ...


7

Overview what the code is about. It may be obvious when you write it, but not two years later, so write down when this code is used in the application, why it is used and so on. Like "this code handles the situation where a user fills out a form complaining about returned packages lost in the post". Answers the question "what the hell is this code for". If ...


7

It's not a bad practice... it all depends on what the function is doing, and whether the code in the function needs to be within a loop, or whether it can be refactored outside of a loop. A function is just a set of instructions, so you could, theoretically, take any function's instructions and put them directly inside the loop, and you have essentially the ...


7

Languages can force or encourage programmers to address certain classes of bugs, which is part of the definition of clean code. For example, various languages do a relatively decent job of addressing: Null pointer exceptions. Shared state bugs. Concurrency issues. Unchecked exceptions. That only gets you part of the way there, though, because clean code ...


7

Your parsedDate method doesn't need the throws Exception clause because the exception is already being caught. The compiler looks at the method signature when a method is called and sees throws Exception, so it expects you to handle it.


6

To some extent. Many languages are deliberately designed to encourage some forms of clean code according to the ideals of the language designers. It is certainly possible to write ugly and incomprehensible code in any language, but some languages do make more of an effort to discourage it. As an example Python forces you to indent blocks according to the ...


5

If one makes a change to an application which will cause a three weeks manual test cycle, the person or the team is not "always done", not even close. If that is your situation, then it should be obvious that keeping the change locally is clearly the better option. However, if you have an automatic test suite at hand with a high test coverage, which can do ...


5

Getters and setters are not evil per se, they're evil when they're used for things they shouldn't be used for. As there are cases when using a getter is inevitable, there are also cases when using the Tell Don't Ask principle is much better suited as a solution for the problem rather than a get* method. Why are getters exactly frown upon then? It's quite ...


4

Is it pythonic to use properties to limit the mutability of class attributes (variables and methods)? For attributes/properties/variables at either the class or instance level: yes, absolutely! The decorator @property is built in specifically to give control over read, write, and delete. Common use cases include: enforcing read-only or write-only ...


4

As you seem to not want to ship the code check to the customer (but seem fine to do it for the programmer) you could use assert functions, if they are available in your programming language. That way you have the checks in the development environment (and any tests a fellow dev would call WILL fail predictably), but you will not ship the code to the ...


4

The introduction to your question makes me think you haven't learned to code properly. Anyone who is programming in an imperative language for more than a few weeks should really be getting their loop bounds right first-time in more than 90% of cases. Perhaps you are rushing to start coding before you've thought through the problem sufficiently. I suggest ...


4

As long as you want only a PDF version of your report, it's enough to simply apply good factoring practices. Write utility functions, extract common code into subroutines, choose good method names, and after a while you'll have a pretty decent maintainable report generator. However, the second it looks as if you'll have to support any other output format ...


4

I'm sure there are situations where this would make sense to do, particularly if you're writing a small application, but in general I think it would be a bad idea. You could apply any argument that you could make about global variables to static variables - they're still changeable anywhere in the application. If your application (and dev team) is ...


3

Looking at this problem more generally than the current answers do, which have mostly focussed on initialization. Consider an object that will have two methods, a() and b(). The requirement is that a() is always called before b(). You can create a compile-time check that this happens by returning a new object from a() and moving b() to the new object ...


3

Protecting a class from mis-use is only one reason for avoiding inspectors/mutators (getters/setters). The other reason is to enforce cohesion and separation of concerns by making sure that behaviour which logically belongs to a class is defined in that class, and not elsewhere. For example, consider the relationship between a Driver and their Vehicle; you ...


3

If you can quantify it, you can create a language that can optimize it. While I don't know of any particular language that actually enforces a "clean code" policy, style cops that run on build are quite common. The main reason that this is a separate step from being baked into the language is largely a function of priorities. It's in the best interest of a ...


3

Off-by-one errors are one of the most common programming mistakes. Even experienced developers get this wrong sometimes. Higher level languages usually have iteration constructs like foreach or map which avoids explicit indexing altogether. But sometimes you do need explicit indexing, as in your example. The challenge is how to think of ranges of array ...


3

This is not a good idea because you can introduce a race condition. In one thread you change the value to one you want but before you manage to create an instance of the class another thread changes the value, and you get an instance created with the wrong default value. Your hair will grow whiter than mine, trying to figure out why things aren't working ...



Only top voted, non community-wiki answers of a minimum length are eligible