2

Hi ive been reading on some similar topics here but none of them answer my question. Some say you cant even do this which is not a good thing since I cant finnish my course in that case.

Heres som simple code. Think of each block as a separate class.


public interface Interface {

    void printMessage(String meddelande);

}

public class Model implements Interface {

    String message = "hej!";

    public static void main(String[] args) {

        Model model1 = new Model();

        View view1 = new View();

         model1.printMessage(model1.message); //Ska jag anropa funktionen såhär ens?

    }

    public void printMessage(String str) {

    }

}

public class View implements Interface {

    printMessage(String str) {

    }

}

So, how is it now possible to tel the view to print this string from the model class without the classes knowing about each other? Its not allowed to send a reference of the model-objekt to the view-object. ; (

msp
  • 3,272
  • 7
  • 37
  • 49

2 Answers2

1

Define an Interface:

public interface MyInterface {

    void printMessage(String str);

}

Define a class that can trigger the notification:

public class ClassNotifier {

    MyInterface mInterface;

    public ClassNotifier(MyInterface mInterface) {
        this.mInterface = mInterface;
    }

    public void triggerTheMsg(String msg) {
        if (mInterface != null) {
            mInterface.printMessage(msg);
        }
    }
}

Define a class that will be informed:

public class InformedClass implements MyInterface {

    public static void main(String[] args) throws Exception {
         InformedClass c = new InformedClass();
         ClassNotifier cn = new ClassNotifier(c);
    }

    @Override
    public void printMessage(String newMsg) {
        System.out.println("A new msg is here: " + newMsg);
    }
}

How does it works?:

this is named a callback parttern, the class ClassNotifier has a reference to the interface MyInterface, which is impl. by Informed class to, so every time the ClassNotifier calls the method printMessage, the method printMessage in the class Informed will be triggered too.

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
  • That looks almost like what I need. So in your example the Informedclass would be the view that prints stuff and the classNotifier would be the model that has all the data? – Peter Kanerva Mar 23 '16 at 14:33
  • But this would mean that i would be sending the view to the model? Which i dont Think is right. I should be sending the model to the view? – Peter Kanerva Mar 23 '16 at 14:34
  • you can adapt the code, what you need for sure is: 1 class that uses the interface and one class that can receive the notification – ΦXocę 웃 Пepeúpa ツ Mar 23 '16 at 14:36
  • Yeah but i want the InformedClass to do the printCommand, i dont want the model to print stuff. – Peter Kanerva Mar 23 '16 at 15:43
  • then you can define create and call a method in the InformedClass – ΦXocę 웃 Пepeúpa ツ Mar 23 '16 at 15:58
  • @ΦXocę웃Пepeúpaツ I have difficulty understanding the need for an interface. Since I am passing an instance of InformedClass as in your example, then why not just call c.printMessage directly from the ClassNotifier instance and save all that headache? – Mena Jan 08 '20 at 09:49
  • ClassNotifier is the one that invokes the printMessage method... so that instance is the one calling x.printMessage("foo")... you can for sure do c.printMessage if you have access to the instance... – ΦXocę 웃 Пepeúpa ツ Jan 08 '20 at 10:30
  • @ΦXocę웃Пepeúpaツ But I will always have an access to the instance, as it has to be passed anyways to initialize the interface in the Notifier class. Sorry if my question sound stupid, but instead of receiving an interface in the Notifier class, just receive the instance of the InformedClass ? Or is it just to be able to receive generic types that implement the interface ? – Mena Jan 09 '20 at 11:11
0

I advice you to use dependency injection, for example:

public class Model {

    String message = "hej!";
    Interface printer;

    public void Model(Interface printer) {
        printer = printer;
    }

    public static void main(String[] args) {

         Model model1 = new Model(new View());
         model1.printMessage(model1.message); 

    }

    public void printMessage(String str) {
        printer.printMessage(str);
   }
}
  • I recommend typing `this.printer = printer;` then. – Manu Mar 23 '16 at 14:07
  • I think it is the other way aroud. This way the Model knows about the view... And the view shouldn't implement the interface... – AFP_555 Mar 23 '16 at 14:09
  • i also Think that the view should know about the model but not the other way around! How could i get it to work the correct way around?! – Peter Kanerva Mar 23 '16 at 14:37