However, many feel that applying OOP to software that is not for physical simulation has led to a huge amount of wasted effort over the previous decades. The problem is with code reuse. The only real form of code reuse that OOP addresses is direct object inheritance. If you want to reuse a piece of code, the way to do it is to make an object that is a 'subclass' of an object that has the code that you want to use. The actual relationship of these objects is often not that simple, and people often create baroque inheritance trees to force their logic into the OOP pattern. Worse, is that OOP is built into many languages, which leaves you no choice.
An alternate pattern is functional programming, where a program is modeled as a series of data transformations, instead of a universe of interacting 'objects'. To write the code, one looks at what data will go into the software, and what data will need to come out. After all, if the right data is coming out of the program at the right times, it works.
Instead of breaking code into objects, you write functions that process the data correctly, and assemble them into larger structures, often resembling pipelines. The nice thing is that a lot of these functions are very reusable across projects and within a project. Avoiding the messy mixture of code and data allows you to identify the common patterns in your code, and refactor and reuse more easily.
EDIT: Here are a couple of libraries which have really facilitated functional programming for me in node.js