Is a method named createOrUpdate() violating the single responsibility principle?
No.
Why? Because:
Robert C. Martin, the originator of the term, expresses the principle as, "A class should have only one reason to change,"
Wikipedia - Single Responsibility Principle
And, like you said, this is a method. Not a class.
Maybe you're thinking of "do one thing". As in:
Functions should do one thing. They should do it well. They should do it only.
Clean Architecture - Robert Martin p35
The problem is, every function does more than one thing. So what does this rule even mean? It means everything that does and doesn't belong in the function must be defined by one thing. It means there should be some single thing that covers everything the function does. Anyone who knows that thing should not be surprised by what they find in the function. See also PoLA
One Level of Abstraction per Function
In order to make sure our functions are doing “one thing,” we need to make sure that the
statements within our function are all at the same level of abstraction.
Clean Architecture - Robert Martin p36
Note the word "statements" is plural. As in, you can have more than one statement in the function that only does "one thing". Therefor, "one thing" doesn't mean that the function can't be decomposed. It can both add and subtract. It can both create or update. That's fine. We just want some "one thing" that makes clear what those things are.
What you really need is a better name.
Let’s assume the point of your method named createOrUpdate()
is it's post condition: something exists. You could chose to name it, not after the statements it contains, but after the point of calling it. After it has been successfully called something has been ensured to exist. So a better name might be ensureExists()
.
Named that way you're free to refactor it so it contains different statements like write
or new
. By keeping the statements out of the name we've hidden implementation details. Done this way, no promise has been made about how the method works. Just what you can count on it doing.
This puts the methods name at a higher level of abstraction. It's still one thing. createOrUpdate()
was also one thing, just didn't look like it. The improvement here is that now the name is focused on what the caller cares about. Not what the implementation is doing.
That's the real reason to rename this. I don't want to be surprised by what I find inside. But I don't want to find the insides leaking into the name.