Upgradeable Contracts -> Use of Initializer AND Constructor?

I was doing a code review on a protocol and I noticed that in one of their contracts (that is upgradeable), they have both a constructor AND and initialize function.

My understanding from the docs is that upgradeable contracts ONLY use an initialize function. I have not read anywhere relating to using BOTH (or why you would use both if there is a difference).

When I look at the actual constructor arguments, I noticed that they are all address that are declared in the smart contract as such:

address public immutable SAMPLE_ADDRESS;

The arguments in the initialize are all values that can be changed (they have setter functions in the codebase to change the values).

Any clarity surrounding constructors AND initialize within a contract would be very helpful to understand why it was designed with this pattern.. Thank you!