A conflict that has come up a few times is using composition and a pass through or a base class
I favor pass through; I write it that way Everytime.
The other engineer on the project favors a base class.

Here's an example of what we've encountered a few times in the project at work.

public class CacheFoo : IFoo{
  private ICache<IFoo> _cache:
  Private IFooer _fooer:
//Berevity
  Public IBar IFoo.ABar() => Cache().ABar();
  Private IFoo Cache()=>_cache.Retrieve(_fooer.Load());
}

This is a pass through. It knows how to cache.

The other version is more of a factory

public class CacheFooFactory : IFooFactory{
  private ICache<IFoo> _cache:
  Private IFooer _fooer:
//Berevity
  Public IFoo Foo => _cache.Retrieve(_fooer.Load());
}

Looking at this; I find value in both. I find myself implementing the pass through most often. Which we refactor into the other when the other engineers get in.

Why?

I don't have a solid opinion on which is "better". When I can't find a reason my favored should win; I'll lean to what the other engineers favor.
Often this is so that it'll eat at me and the brain will find the argument/answer for me.

A dozen implementations of passthrough refactored to factory - I don't have winning arguments for either. This is that I can't even convince myself that my favored is "right". I like the flow of treating the CacheFoo as an IFoo. The code reads simpler to me. It has to know how to do less. The implementation of the collaborator can change; but the behavior doesn't.
While this is true of the Factory as well... I'm seeing that the point which may become my main thrust - I'll see how it flies with the team on Monday -

A factory as a collaborator forces all instances of the concrete classes to have an associated factory.
CacheFoo must have a CacheFooFactory.
FileFoo must have a FileFooFactory.
NetworkFoo must... Each concrete IFoo; for appropriate polymorphism and decoupling; must have an associated Factory. Require it for one - it's driven to all. Or else you rewrite you class implementation from IFooFactory because you need a different Foo.

This is wrong.

While I was heavily leaning to the pass through; this provides me with a compelling argument. It's not less layers; or less abstraction; the win here is the simplicity of the implementing code. The stupidity of the implementing code. It doesn't have to care that what it has doesn't DO it for us - it will get it done for us.

Factories are a code smell to me; this is a factory - it's really started to stink.

Neat. I'll be sticking to passthroughs in new code. I'll leave work's paradigm alone... For now! Hehe

Tangent - I enjoy how writing this stuff out really helps me think it through and solidify points and be able to communicate the notions in my head.