Well! Maybe Mathematica doesn't provide the "best" way to deal with this problem. It's the user's job to come up with solution of it.

My solution: 1) MapThread; 2) Table

Clear["`*"];

a = {a1, a2}; b = {b1, b2}; ref1 = {x1, y1}; ref2 = {x2, y2};

oA1 = Plus[a, ref1];

oA2 = Plus[a, ref2];

oB1 = Plus[b, ref1];

oB2 = Plus[b, ref2];

{{oA1, oA2}, {oB1, oB2}}

MapThread[Plus, {{{a, a}, {b, b}}, {{ref1, ref2}, {ref1, ref2}}}]

Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]

(*

Result:

{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}

{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}

{{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}}, {{b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}}

*)

These are my provisional solutions. For the moment, Table is the best choice.

By the way, MapThread also has its merit.

{oA1, oA2, oB1, oB2} = MapThread[Plus, {{a, a, b, b}, {ref1, ref2, ref1, ref2}}]

(*

Result:

{{a1 + x1, a2 + y1}, {a1 + x2, a2 + y2}, {b1 + x1, b2 + y1}, {b1 + x2, b2 + y2}}

*)

You don't need to Flatten the result and four points are directly assigned to variables.

With Table, you have to use Flatten or more curly braces.

{oA1, oA2, oB1, oB2} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]~Flatten~1

{{oA1, oA2}, {oB1, oB2}} = Table[Plus[x, y], {x, {a, b}}, {y, {ref1, ref2}}]