My professor said that converting a language to a CFG is more of an art than anything else. I looked at this problem and didn't even know how to get started, or how I would reason my way to the solution (which I understand how it is correct).
Are there any useful patterns to deal with these conversions?
For the language given, you need the number of $a$'s to match up with the number of $b$'s. Notice that the strategy used to find a CFG for the language is to make sure that whenever we introduce an $a$, that we also introduce a $b$ at the same time. By doing this, we make sure that the number of $a$'s and $b$'s are equal. Also, whenever we introduce an $a$ or a $b$, we also want the ability to put substrings on either side of them or inbetween them, hence the $S \to SASBS$ and $S \to SBSAS$ production rules. Notice that since the empty string also has the same number of $a$'s and $b$'s, then we need the $S \to \varepsilon$ production rule.
From this point, it is clear that everything that is in the grammar is also in the language. What's not so clear is that everything in the language is produced by the grammar; however, it turns out that these production rules suffice for generating the entire language (this isn't too difficult to prove).