It's an interesting question, and while a concrete, definite answer perhaps requires a precise definition of what "expressed" means, in general, I would agree that the structure of the strategy pattern
[Context]--->[Abstraction]<|-----[Derivative]
is the basic underlying form that appears in various forms in many other patterns. This is also the basic structure you get by applying the Dependency Inversion Principle (from SOLID):
[A]--->[Abstraction]<---[B]
In general, the 'abstraction' does not have to be an abstract class or an interface, but any kind of contract that captures the nature of the interaction between the two components (e.g., it could be a contract of some sort, a protected interface only visible to subclasses, or some kind of a language, a data structure, a set of conventions, etc.).
Now, in the Go4 book, the patterns are not so much differentiated by structure as they are by their intent (e.g., the structure of Strategy and State, and Bridge is more or less exactly the same), and in fact, the details of the structure are free to vary in some ways. I don't quite see the Template Method pattern the same way (I think) you do, though. You can have common code in the abstract Strategy as well (it doesn't have to be an interface). Their basis for making the Template Method a distinct pattern is really predicated on it's intent (or the kind of problem it solves), which is to impose a certain structure on an algorithm and let the derivatives change parts of it. They do compare and contrast it with Strategy, saying that "Strategies use delegation [by which they mean composition] to vary the entire algorithm" while "Template methods use inheritance to vary part of an algorithm". In other words, they only consider the [AbstractTM]<|---[ConcreteTM]
pair to be the part of the pattern (essentially, there's no external "Context"). But that's not necessarily the perspective that's useful to what you're trying to do. One way to look at it is that the public TemplateMethod()
(the function) relies on an abstraction represented by the set of protected primitive operations that can be overridden, which then lets you write the TemplateMethod()
in a generalized way:
[TemplateMethod()]---->[protected primitive ops]<|---[overriding implementations]
And in fact, if you decided to pull out those protected primitive operations into, say, an abstract class (essentially utilizing the Strategy pattern), nobody could really claim that what you're doing is wrong.
To me, there isn't really a fundamental difference there. So, yeah, in general, wherever there's a need for a dependency to be inverted, you'll find some variation of that structure. So, I'm inclined to say that in many cases you could do "the same job" using that same basic structure. But since patterns aren't strictly defined by their structure, but rather by what they are trying to do and by the way their elements interact and collaborate to achieve that goal, what you'd end up with could still be described as those respective patterns. What you've stumbled upon here is a principle that's deeper (more fundamental) than the patterns themselves are.
The Decorator pattern is a bit specific in this regard, and it's worth understanding in what way. There's the same sort of dependency structure embedded in it too, but the thing that's specific to it is that the abstraction referenced by the "Context" (the AbstractDecorator) is also the one that the Context itself derives from (this is important because (1) it allows decorators to be transparent to client code, and (2) it allows decorators to be stacked on top one another). The other thing to notice is that decorator is not necessarily extended by deriving from that abstraction, but by deriving from the AbstractDecorator itself (assuming there's a base decorator that provides the basic wrapper capability).
I don't know how well all this answers your question, but hopefully you'll find it useful in some way.
P.S. I wouldn't say that Visitor solves (strictly speaking) the expression problem, but rather lets you flip it around. Objects make it easy to add new representations (by deriving classes), but make it harder to add new operations (methods) to the abstract interface. Visitor makes it easy to add new operations (new Visitor derivatives), but it's hard to add new representations (new types of elements).
P.P.S. In case my ad hoc ASCII diagrams aren't very clear:
---->
- a dependency (in a general sense, not necessarily a direct reference)
---|>
- an inheritance relationship
(the arrows define the dependency direction)