A discretize-then-optimize approach to PDE-constrained shape optimization