1) Name your classes/interfaces with specific names instead of “Default” or “YourCustumer” prefix.
First of all, we have to keep this important thing in mind: we are coding general and abstract business and technical rules. “Coincidentally”, these rules are being used by our customer. (To make things clear, the customer here means the company that are paying you (or your employer) to customize the hybris).
Suppose that you are defining a new way of adding a product to cart, that is, you will add the product (default behavior) and change all quantities to one (new behaviour). This new behavior is exclusive to your customer now, but it may not be in the future.
So, don’t name your Class as “MyCustomerCartService” or “DefaultCartService” or, even worse, “DefaultCartServiceImpl”. Use the specific behavior name, for example, “SingleQuantityCartService”.
2) Create a new specific interface instead of extending an existing one
The most common “mistake” that I see is inserting new methods into an existing (OOTB) interface. You should avoid it at all costs because otherwise, you will end up with a giant and too generic contract. Remember that one of the SOLID principles is the “Interface Segregation Principle”. It states that a client should not depend on methods that they don’t use.
Therefore, if you need to create a new way (method) of doing something, you shouldn’t extend the existing interface, but create a new one that represents this new method.
For example, suppose that we have to create a new cart using the CartFactory, but instead of creating an empty cart we have to create it with default products that we will receive as parameter. In this scenario, we shouldn’t extend the CartFactory inserting all our methods there because we are creating a giant interface and obviously breaking the Interface Segregation Principle. In this case, the most convenient way of customizing it is creating a new interface (or a new implementation of the old interface) named something like “FilledCartFactory” and insert our methods there.
3) You should use decorators over inheritance
The concept of composition over inheritance is not new. https://en.wikipedia.org/wiki/Composition_over_inheritance
Sometimes extending a bean may seem easier than recreating it, but we have to remember that all components (facade, service, strategy, dao) implement a contract (interface), so we should stick to this contract whenever it is possible.
There are situations that we have to adjust the functional aspect of a class (service, strategy e etc) and it may sound tempting to extend the default class through inheritance and override the default behavior. It’s natural to think like this because it’s an easy way to do it (and it’s how the trails teach us). However, using the java standard extension with hybris OOTB classes tends to generate a big technical debt in the long term. The java traditional extension creates big classes and big interfaces. Soon or later, we will break encapsulation, Single responsibility and/or Interface segregation principles. So, the best way to do this is by using decorators (the decorator pattern).
I’m not going to write how to create decorators, because we have a lot of good content about it: https://www.yegor256.com/2015/02/26/composable-decorators.html
Therefore, everytime that you think about creating a new interface, extending an existing interface or extending an existing class, check if there is a better way of doing this, probably you will come up with a more elegant solution using decorators.