Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Friday, October 20, 2023

Sunday, January 6, 2019

Test-Driven Development - you are doing it wrong!

Test-Driven Development is one of those techniques that somehow is not as widely used as it should be. I know a lot of developers who can agree on the benefits it brings. Yet the same developers, when asked about practicing TDD, answer: “it does not work for me”.
When I tried to understand the “why” behind this statement, they start to struggle to find an explanation. They say they only add simple features. They say their application is not that complex. They have no time. Many of them tried, but it was “too time-consuming”, it cost too much effort.

I pair with some of them. On a couple of occasions I had long conversations with them to understand how they were doing it? What went wrong? What’s the conclusion? In many cases, the problem lies in the basics - they simply tried to apply TDD to every newly created object.

Tuesday, June 5, 2018

Just stop for a moment

I know there are deadlines in front of you that need to be met. They are the reason why you keep writing code. They are the cause of your lack of time - you are running from one deliverable to another, trying to deliver as fast as possible. Trying to deliver with the highest quality possible.

Friday, March 3, 2017

The code that does not have to be written

Do you know which code is best? It’s the one that does not have to be written at all!

As developers we often solve non-trivial problems. We have to analyze and understand each important aspect of a problem. Then we have to “convert” the result of such analysis into code. This code has to meet all the requirements. It has to be understandable. To achieve this, we talk about design and structure of the code and sometimes challenge it to make it better. And after a while we are there, with a clear picture in our heads. Now the funny part begins, now’s the time for coding!

Tuesday, January 10, 2017

Lazy-loading is a Code Smell

Have you ever seen those huge objects with many attributes? These domain objects where we are using lazy-loading because we do not want to retrieve too much information from the database? I bet you’ve had this doubtful pleasure.

Today I want to share with you my impressions about them - using lazy-loading should be treated as a code smell!
Let me explain myself:
  • Lazy-loading means that sometimes you won’t need some attributes of an object. Those attributes will be necessary in a different context. Doesn’t it mean that you are building different objects depending on context?
  • The functionality that is using this object knows definitely too much. It knows the API of the object and this API contains also the methods that require attributes which were not loaded. Great, isn’t it?
  • You have to remember what is needed in each place and what is not needed …
  • … and, what is even worse, you have to remember what you may use and what methods are not supported in a particular place.

Tuesday, October 25, 2016

Do you really need instanceof?

Using instanceof is a code smell. I think we may agree on that. Whenever I see a construction like that I’m sure that something went awry. Maybe someone just didn’t notice a problem when making a change? Maybe there was an idea, but it was so complex that it required so much effort or time that a developer made a decision not to do it? Maybe it was just laziness? Who knows. The fact remains that the code evolved into such state and we have to work with it.
Or maybe there is something that we can do about it? Something that will open our code for extensions?

Friday, July 15, 2016

Many parameters and lost information

The less code, the better? The fewer objects, the better? Is it true? As usual, it depends.

There are cases when by adding something more we are adding unnecessary complexity. It happens when we are creating interfaces or other abstractions just because “we may need this additional flexibility in future”. It happens when we forget about YAGNI principle and we are writing code that may make our life easier in case of new requirements that… may never come.

Wednesday, July 6, 2016

Implementation, behavior and the amount of the code...

Implementation, behavior and the amount of the code... Today is the right time for another code-related question that I’d like to ask.
Take a look at these methods:
refactoring.setState(IN_PROGRESS);

refactoring.setState(VERIFIED);

refactoring.setState(DONE);

To make everything clear, we can easily assume that each invocation is done in a different place and after different activities have been completed.
There is nothing exciting in this code and probably you saw something similar in your code bases many times. Nothing complicated. We are just changing the state of the object.

So, now’s the time for the question: what’s wrong with this code?

Friday, June 17, 2016

Conjunctions we... hate

Recently I’ve written about implementation-related names and I’ve presented a few examples where the method name was incorrect because of its strong relation with the body.
At one moment, we had the following code:
boolean isComplexOrUnreadableWithTests() { 
    return (complex || unreadable) && tests.exist(); 
}

Just to remind you of the context: it was supposed to find out whether we may or may not do the refactoring:
if (code.isComplexOrUnreadableWithTests()) {
	doRefactoring(code);
}

Recently I’ve told you that the name is wrong because of its direct relation to the implementation. However, this is not the only problem. The use of conjunctions in the method’s name is a sign that we could not find a right name and we just list all known things that we’ve done. It does not matter whether this list is implementation- or logic-related.

Saturday, June 11, 2016

The name should express the intention

This time I will start with a code sample. Take a look at this:
if (code.isComplexOrUnreadable()) {
    refactor(code);
}

Can you tell me what is wrong with this code? No?

Let me ask you another question then. How do you think the implementation of isComplexOrUnreadable() method looks like?
I assume that many of you would imagine something similar to this:
boolean isComplexOrUnreadable() {
    return complex || unreadable;
}

Am I right?

Ok, so let me ask you again: can you tell me what is wrong with this code?

Wednesday, March 16, 2016

@Autowired all the things!

Recently I have written that @Autowired annotation make our lives easier in that it allows us to write less code. However, using it may often make your design more complicated. Especially when we are talking about using it on class’s properties. It makes it easier to violate Single Responsibility Principle. It makes it easier not to notice that.

It is ok to use @Autowired with properties, yet, I think, that presence of the constructor visualizes the problem with too many dependencies when it occurs. Even without exercising additional care from our side.

Monday, March 7, 2016

@Autowired and optional dependencies

@Autowired annotation makes our lives easier. It also can result in decreased amount of code if we are using it on properties of the class. We need neither constructors nor setter methods. It looks great at first glance, but the benefits rarely come without cost.

Today I want to make you aware of the costs that have to be paid.

Sunday, February 21, 2016

Constructor or setter?

It goes without saying that every object needs to be created before it can be used. It does not matter whether we are talking about a domain, frameworks, libraries or any other type of the classes. When your code is an Object-Oriented, those classes are only definitions of the objects. You cannot use objects before they are created.

When we are talking about object’s initialization, we often need to think about dependencies. How will you inject them? Will you use the constructor or setter?

Sunday, February 7, 2016

Wednesday, December 16, 2015

Growing Object-Oriented Software, Guided by Tests

It’s been awhile since my last post. Recently, there have been many conferences and meetups I had pleasure to spoke at. Making presentations, carrying out research, readings, conducting reviews, etc., everything takes time. I need to admit that I like each part of this process, because I always learn something new. Even if I’m reading the same materials, blogs, books, even if I’m thinking once again about the same topic, I always find some things I didn’t noticed before.

Monday, November 16, 2015

Tell, don't ask

about rules and principles

Some time ago I wrote about the Law of Demeter, about the advantages of following this law. Today I would like to write about the “Tell, don’t ask” principle. The principle that is, at least in my opinion, the starting point for the mentioned law. Following LoD is one of the consequences of applying the TDA principle.

Ok, but what should we tell and what shouldn’t we ask about anyway?

Monday, October 26, 2015

Where's the law?

If you would like to describe Law of Demeter in one sentence, it would go like that: “talk only with your (closest) friends”.
In full form it tells that a method of particular object can call only methods that belong to:
  • the same object,
  • any object that is an attribute of this object,
  • any object that was passed as a method’s parameter
  • any object that was locally created.

Wednesday, October 7, 2015

OOP: How to do it right. What the method is?

Some time ago I wrote about objects' attributes. Parts that identify them. However, the objects are exactly like us - it’s our behavior that determines who we are, makes us who we are. This behavior and reactions are the things that really interest others. Would Sebastian be the same annoying person if his name were different? Assuming there's no magical power in our names he probably would.

Don't get me wrong, I don't want to minimise the importance of object's attributes. The behavior of the object often depends on them, e.g. if the age is one of person’s attributes, it's clear that it determines many activities that the person can or cannot do.

Tuesday, August 11, 2015

Do you really want to test it?

I’m probably not the only one who had a chance to participate in deliberations over whether some private method should be tested (because it’s worth it) or not (because we shouldn’t test private methods). I’m not writing about pure theoretic conversations while you’re filling your cup of coffee and talking with your colleagues. I believe that in those moments most of developers would tell you a firm NO.

But what about situations when you are working with real code? When all those rules and principles are not so strictly followed? Would they also say NO so firmly? Based on my experience, I can tell you they wouldn’t. At least not always.

Ok, but should they? Should we? Or is it yet another nice-to-follow rule the observance of which depends on context?