Extending Constructor-based Contracts to Upgradeable

I have some contracts that rely on their constructors for their state. I want to make my contracts upgradeable and support deploying the state to a proxy contract and the logic to an implementation contract. I would like to keep my non-upgradeable contract as is and use extension/inheritance to create an upgradeable contract. Are there strategies for accomplishing this without duplicating code and tests?

Here's one of the contracts I want to extend into an upgradeable version:

https://github.com/EvanPiro/Contracts/blob/main/contracts/Forward.sol

I found a way to do this:

Move the entire implementation of the contract with a constructor into a base contract that has an initialize function containing the constructor logic and remove the constructor. Then you can recreate the original contract with a constructor:

import "./ForwardBase.sol";

/**
 * @title Forward
 * @dev ForwardBase but with a constructor
 */
contract Forward is ForwardBase {
    constructor(address priceFeedAddress, uint unlockTime) payable public ForwardBase() {
        initialize(priceFeedAddress, unlockTime);
    }
}