It should be a comment, but I have too many words.
For example, you have an object and an interface, for example Repository: IRepository
.
public interface IRepository { void SaveStuff(); } public class Repository : IRepository { public void SaveStuff() {
and a client that was probably written by someone else
class RepoClient { public void DoSomething(IRepository repo) {
And as soon as you decide that ALL accesses to the repository should be registered. But you have a problem: the Repository
class from an external library, and you do not want to modify this code. Therefore, you need to extend the Repository
behavior that you use. You write RepositoryLogDecorator: IRepository
, and inside each method RepositoryLogDecorator: IRepository
logging, like
public class RepositoryLogDecorator : IRepository { public IRepository _inner; public RepositoryLogDecorator(IRepository inner) { _inner = inner; } public void SaveStuff() {
So, before you could use the client as
var client = new RepoClient(); client.DoSomething(new Repository());
but now you can use
var client = new RepoClient(); client.DoSomething(new RepositoryLogDecorator(new Repository()));
Please note that this is a very simple example. In real projects, where the object was created primarily with a DI container, you can use the decorator by changing some settings.
Thus, the decorator is used to expand the functionality of the object without changing the object or client.
Another advantage of the decorator: your decorator is independent of the implementation of the Repository
. Only depends on the IRepository
interface. Why is this an advantage? If you decide to write your own implementation of IRepository
public class MyAwesomeRepository : IRepository { public void SaveStuff() {
You can automatically decorate this with a decorator that already exists.
var client = new RepoClient(); client.DoSomethig(new RepositoryLogDecorator(new MyAwesomeRepository()));
Want to see an example from real software? (as an example, the code is ugly, I know) => go here