Os construtores são mais úteis quando seu objeto precisa de muitos argumentos / dependências para ser útil, ou você deseja permitir várias maneiras diferentes de construir o objeto.
Em cima da minha cabeça, eu posso imaginar que alguém possa querer "construir" objetos em um jogo 3D como este:
// Just ignore the fact that this hypothetical god class is coupled to everything ever
new ObjectBuilder(x, y, z).importBlenderMesh("./meshes/foo")
.syncWithOtherPlayers(serverIP)
.compileShaders("./shaders/foo.vert", "./shaders/foo.frag")
.makeDestructibleRigidBody(health, weight)
...
Eu diria que este exemplo é mais legível com os métodos construtores que criei agora do que com parâmetros opcionais:
new Object(x, y, z, meshType: MESH.BLENDER,
meshPath: "./meshes/foo",
serverToSyncWith: serverIP,
vertexShader: "./shaders/foo.vert",
physicsType: PHYSICS_ENGINE.RIGID_DESTRUCTIBLE,
health: health,
weight: weight)
...
Em particular, as informações implícitas nos nomes dos métodos do construtor precisam ser substituídas por mais parâmetros, e é muito mais fácil esquecer um parâmetro em um grupo de parâmetros intimamente relacionados. De fato, o shader de fragmento está ausente, mas você não notaria isso a menos que soubesse procurá-lo.
Obviamente, se o seu objeto precisar de um a cinco argumentos para construir, não há necessidade de envolver o padrão do construtor, independentemente de você ter nomeado / não parâmetros opcionais.