Objects responsible for too many things are a problem. Because their complexity is high, they are difficult to maintain and extend. Decomposition of responsibility is what we do in order to break these overly complex objects into smaller ones. I see two types of this refactoring operation: vertical and horizontal. And I believe the former is better than the latter.
Each software team organizes its communications in its own specific way. Some use Slack, Trello, or GitHub; others just sit together in the same room. There are many methods and tools. I believe it's possible to rank them by the amount of damage they cause to your project. This is the list of all of them I'm aware of at the moment.
Recently, I was trying to convince a few of my readers that a better understanding of an object in OOP would help us solve many problems in existing pseudo-object-oriented languages. Then, suddenly, the question came up: "What problems?" I was puzzled. I thought it was obvious that the vast majority of modern software written in modern OO languages is unmaintainable and simply a mess. So I Googled a bit, and this is what I found (in chronological order).
In most cases (maybe even in all of them), if-then-else can and must be replaced by a decorator or simply another object. I've been planning to write about this for almost a year but only today found a real case in my own code that perfectly illustrates the problem. So it's time to demonstrate it and explain.
OK, the title is not exactly accurate. I've missed the "can" word. A distributed team can deliver code of much higher quality than a co-located one, and now I'll explain why. Of course, not every distributed team can do that. Most of them can't even deliver code that works, let alone quality code. But if a team—a distributed one—is managed according to the principles I'll explain now, the quality will be much higher than the same team can achieve if co-located. What I'm going to show you is that working in a remote mode, if done right, guarantees higher quality of code. Surprised?
There are a number of levels you have to go through before your continuous integration pipeline becomes perfect. I found eight of them and presented my findings at DevOpsDays in Salt Lake City a few weeks ago (watch the video). Now it's time to write them down and ask you—Which level are you at? Post your answer below.
You probably remember what I think about ORM, a very popular design pattern. In a nutshell, it encourages us to turn objects into DTOs, which are anemic, passive, and not objects at all. The consequences are usually dramatic—the entire programming paradigm shifts from object-oriented to procedural. I've tried to explain this at a JPoint and JEEConf this year. After each talk, a few people told me that what I'm suggesting is called ActiveRecord or Repository patterns.
I've already explained how I understand the role and responsibilities of a software architect. But one question still remains unanswered, and it often turns into a problem in our projects: What does a software architect do when the project sponsor doesn't like his technical decisions? The architect implements something in a certain way, and the sponsor (or its representative) says that it's not exactly how things should work. What's next?
You've probably heard about that 30-year-old Law of Demeter (LoD). Someone asked me recently what I think about it. And not just what I think, but how it is possible to keep objects small and obey the LoD. According to the law, we're not allowed to do something like book.pages().last().text(). Instead, we're supposed to go with book.textOfLastPage(). It puzzled me, because I strongly disagree. I believe the first construct is perfectly valid in OOP. So I've done some research to find out whether this law is really a law. What I found out is that the law is perfect, but its common understanding in the OOP world is simply wrong (not surprisingly).
There are thousands of books about object-oriented programming and hundreds of object-oriented languages, and I believe most (read "all") of them give us an incorrect definition of an "object." That's why the entire OOP world is so full of misconceptions and mistakes. Their definition of an object is limited by the hardware architecture they are working with and that's why is very primitive and mechanical. I'd like to introduce a better one.