My first answer explains that Mathematica's replacement rules perform destructuring.
This answer is intended to complement jVincent's method, which I see is appreciated. (This is not a bid for the bounty, which will automatically be awarded to jVincent's answer according to the rules, since the one giving the bounty has departed S.E.)
My aim is to provide AttributesAttributes for the pattern-based function. This requires that the head evaluate therefore SubValuesSubValues may not be used. Here are two separate approaches.
Module
A direct approach is to automate the creation of a new DownValueDownValue function using Module.
SetAttributes[pFunc1, HoldAll] pFunc1[pattern_, body_, attrib_: {}] := Module[{pf}, SetAttributes[pf, attrib]; pf[pattern] := body; pf ] pFunc1[_[__, b_, c_], Binomial[b, c], HoldAllComplete][9 + 7 + 6 + 3] pFunc1[PatternSequence[_[__, b_, c_], x_], Binomial[b, c]/x, HoldAllComplete][9 + 7 + 6 + 3, 4] 20
5
ReplaceAll
The first method creates a new symbol pf$xxx for each use which could be seen as undesirable. A method that does not is to simply embed a ReplaceAll operation in the body of Function like this:
SetAttributes[pFunc2, HoldAll] pFunc2[pattern_, body_, attrib_: {}] := Function[ Null, Unevaluated@{##} /. pattern :> body, attrib ] This method returns an actual Function expression rather than a pf$xxx symbol.
It also allows mixing Slot (#) and pattern references in body should that be desired.
It however does not return aan unevaluated function expression when the arguments do not match the pattern. (Though one could add a {__} :> $Failed type of rule to /., if that is all that is desired.)