Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facade pattern combined with observer pattern

I got an assignment to find out exactly what the facade pattern is. I have googled and found out it is meant to shield a client from a very complex system by making an "interface". So I have a few questions, I have seen in multiple examples is they make an C# interface for the complex system, but I have also seen a few that used A class as the "Interface" (as seen here). I can only make sense of it if it is a base class that simplifies a lot of different complex method calls to different classes as in (the bank example seen here)

  1. So my first question is if I am correct that you would implement the "interface" as a class?

  2. My other question then is, could you use facade pattern together with the observer pattern. The facade class would observe on all subjects and then control what methods in different classes should be called, depending on the subject?


Edit: As requsted I tried to make an example project with a facade for a observer pattern and here is the result:

public class Facade
{

    private Dictionary<ISubject, List<IObserver>> Subjects { get; set; }

    public Facade()
    {
        Subjects = new Dictionary<ISubject, List<IObserver>>();
    }

    public void AddObserverToSubject(ISubject sub,IObserver obs)
    {
        if (Subjects.ContainsKey(sub))
            Subjects[sub].Add(obs);
        else
        {
            List<IObserver> observers = new List<IObserver>();
            observers.Add(obs);
            Subjects.Add(sub, observers);
        }
        obs.Subject = sub;
    }

    public void DeleteObserverFromSubject(IObserver obs,ISubject subject)
    {
        Subjects[subject].Remove(obs);
    }
    public void Notify(ISubject subject)
    {
        foreach (var observer in Subjects[subject])
        {
            observer.Update();
        }

    }
}

public interface ISubject
{
    Facade Observers { get; set; }
    int GetState();
    void SetState(int state);
}

public interface IObserver
{
    ISubject Subject { get; set; }
    void Update();
    string Mood { get; }
}

So every observer will update their mood depending on what is going on with the subject.

I have made two implementations of IObserver and ISubject but I will only show one of each here.

public class TeacherObserver : IObserver
{
    public ISubject Subject { get; set; }
    private int _currentSalery = 500;
    public string Mood { get; private set; }
    public TeacherObserver()
    {
        Mood = "Happy";
    }


    public void Update()
    {
        var newSalery = Subject.GetState();
        if (_currentSalery < newSalery)
        {
            Mood = "Happy";
        }
        else
        {
            Mood = "Sad";
        }
        _currentSalery = newSalery;
    }
}

public class SalerySubject :ISubject
{
    public Facade Observers { get; set; }
    private int _salery;
    public int GetState()
    {
        return _salery;
    }

    public void SetState(int state)
    {
        _salery = state;
        Observers.Notify(this);
    }
}

So one thing I like about this is that the subject doesn't have to know about all the observers that is bound to it(this will be handled by the facade class now). But seeing from the clients view it is pretty much the same calls he would have to make:

class Program
{
    static void Main(string[] args)
    {
        Facade.Facade observer = new Facade.Facade();
        ISubject salery = new SalerySubject();
        IObserver teacher = new TeacherObserver();
        salery.Observers = observer;
        observer.AddObserverToSubject(salery,teacher);
        Console.WriteLine("Teacher is " + teacher.Mood);
        salery.SetState(100);
        Console.WriteLine("Teacher salery just went down. The teacher is now " + teacher.Mood);
    }
}
  1. Which leads me to thinking that it doesn't really make sense to do it with a facade, as the whole point of the facade is to make it easier for the client right? (or hide information) or am I wrong?
like image 520
Sumsar1812 Avatar asked Mar 14 '23 01:03

Sumsar1812


2 Answers

I think the term 'interface' is used in different meanings. You have the general term of 'interface for something' to access it and you have the concret term 'c# interface definition' as part of that language. So i think, in your quote

to shield a client from a very complex system by making an "interface"

the first general meaning is used. And the question is how to build it:

1.So my first question is if I am correct that you would implement the "interface" as a class?

I would use both. First, i would create an c# interface to define the contract, then build a base class as reference implementation. If you use only a base class, then all other possible classes have to inherit from this and they get the implementation details only because they wanted the contract. If the other possible classes can use your interface, they only have to implement it, that means they have to provide the methods in the interface definition and have no link to each other.

2.My other question then is, could you use facade pattern together with the observer pattern. The facade class would observe on all subjects and then control what methods in different classes should be called, depending on the subject?

Yes you can, but then the observing behaviour with all it's classes is 'part' of the facade. If that is what you want, ok.

3.Which leads me to thinking that it doesn't really make sense to do it with a facade, as the whole point of the facade is to make it easier for the client right? (or hide information) or am I wrong?

I think it does make sense to have a facade for the purpose it is defined for, to interface the complex system behind it. Only if there is nothing then the observing behaviour, then there is no complexity to hide.

So may i suggest a little redesign like this:

I would implement ISubject with an event, because it doesn't need to know who is observing, it will simply notify:

public interface ISubject
{
    event EventHandler OnNotify;
}

and then create a second interface to give access to a salary:

public interface ISalerySubject: ISubject
{
    int Salery { get; set; }
}

The IObserver can hold a ISubject:

public interface IObserver
{
    ISubject Subject { get; set; }
}

Now lets get concrete. The class SalerySubject is implementing the interface ISalerySubject, so when the salery is changed the event is fired:

public class SalerySubject : ISalerySubject
{
    public event EventHandler OnNotify;

    private int salery;
    public int Salery
    {
        get { return salery; }
        set
        {
            salery = value;
            if (OnNotify != null) OnNotify(this, new EventArgs());
        }
    }

}

The class TeacherObserver is implementing the interface IObserver and it binds it's method Update to the event of ISubject:

public class TeacherObserver : IObserver
{
    private int _currentSalery = 500;
    public string Mood { get; private set; }

    public ISubject subject;
    public ISubject Subject
    {
        get { return subject; } 
        set
        {
            // Relase old event
            if (subject != null) subject.OnNotify -= Update;

            subject = value;

            // Connect new event
            if (subject != null) subject.OnNotify += Update;
        } 
    }

    public TeacherObserver()
    {
        Mood = "Happy";
    }


    public void Update(object sender, EventArgs e)
    {
        ISalerySubject SalerySubject = Subject as ISalerySubject;
        if (SalerySubject != null)
        {
            var newSalery = SalerySubject.Salery;
            if (_currentSalery < newSalery)
            {
                Mood = "Happy";
            }
            else
            {
                Mood = "Sad";
            }
            _currentSalery = newSalery;
        }
    }
}

Now you can use it:

class Program
{
    static void Main(string[] args)
    {
        ISalerySubject salery = new SalerySubject();
        TeacherObserver teacher = new TeacherObserver();
        teacher.Subject = salery;

        Console.WriteLine("Teacher is " + teacher.Mood);
        salery.Salery = 100 ;
        Console.WriteLine("Teacher salery just went down. The teacher is now " + teacher.Mood);
    }
}   

So, up to this point, there is no need for a facade. Maybe you want to keep a list of observers, but that normally is not stored in a facade. Maybe your system is far more complex, so then there is a good reason for a facade anyway.

like image 102
Dieter Meemken Avatar answered Mar 28 '23 23:03

Dieter Meemken


I got an assignment to find out exactly what the facade pattern is

Facade is just yet another wrapper.
It wraps some entity, usually to hide some details from client.

if I am correct that you would implement the "interface" as a class?

Interface is a contract.

To implement this contract, you need a class (since we're talking about design patterns, I'm omitting structures discussion). In other words, you can't implement facade using interface only, because you need a class, where implementation logic will be placed, but interface could help you to make your components loosely coupled.

Actually, to use interface or not to use is unrelated to particular pattern.

could you use facade pattern together with the observer pattern

In theory - yes, you can. In practice - it depends.

like image 21
Dennis Avatar answered Mar 29 '23 00:03

Dennis