I am trying to solve statediagram exercise, but still have not understood why my code does not work.
I chave already cheked all possible code examles of code, but have not understood why mine version does not pass any tests.May be I chve some sort of small mistake which not easy to see. Below I provide my code, test semples and digramms I have.
https://drive.google.com/open?id=1SQAiwUBo1OwI-QKksxciDS7dEdKGS6dn [1]
https://drive.google.com/open?id=1JhdScK7t1XmNc3eLT7hSGpwyYDLWl46T [2]
public class GarageDoor {
private Motor motor;
private DoorState currentState;
public GarageDoor() {
this.setState(new Closed(this));
//currentState=new Closed(this);
}
public void openDoor(){
currentState.openDoor();
}
public void stopper(){
currentState.stopper();
}
public void closeDoor(){
currentState.closeDoor();
}
public Motor getMotor(){
return this.motor;
}
private void setState(DoorState ds){
this.currentState=ds;
}
public abstract class DoorState{
public abstract void openDoor();
public abstract void closeDoor();
public abstract void stopper();
}
public class Closed extends DoorState{
private GarageDoor garageDoor;
public Closed(GarageDoor garageDoor){
this.garageDoor=garageDoor;
}
#Override
public void openDoor() {
garageDoor.setState(new Opening(garageDoor));
garageDoor.getMotor().upwards();
}
#Override
public void closeDoor() {
throw new IllegalStateException();
}
#Override
public void stopper() {
throw new IllegalStateException();
}
}
}
Actually I cann not execute main()
public static void main(String[] args){
//Motor motor=new Motor();
GarageDoor gd=new GarageDoor();
gd.openDoor();
}
I don't see that you're setting motor anywhere, so in Closed.openDoor, when you call garageDoor.getMotor().upwards() you'll get a NullPointerException.
Also, I see that you're passing GarageDoor in to the Closed state and then calling garageDoor.setState. Consider just returning the next state from each DoorState method.
1) Try having GarageDoor extend DoorState, seems to override the same methods.
2) Nowhere in your code do you actually create the Motor in the GarageDoor class.
You need to initiate the Motor, e.g:
public GarageDoor() {
this.motor = new Motor();
}
Related
So i'm trying to develop a fluent interface for some DSL in Java and am running into a problem. The interface consists of builder pattern classes that each construct part of the DSL. The problem is that a specific builder sometimes needs to transfer control to a different builder which at some point returns to the 'parent' builder. For example, there is a 'SequenceBuilder' that creates a list of statements but it need sometimes transfer control to an 'IfBuilder' that is used to create an 'if' statement. When the IfBuilder is finished, it needs to return to the SequenceBuilder. Now there are some builders that are not always called by the same type of other builder and therefore need to be able to return builders of a different datatype. The example program below demonstrates this:
package com.example.fluent;
public class Test {
public class Type1 {
public Type1 test1() {
System.out.println("test1");
return this;
}
public Type3 gotype3() {
System.out.println("gotype3");
return new Type3<Type1>(this);
}
public void endtype1() {
System.out.println("endtype1");
}
}
public class Type2 {
public Type2 test2() {
System.out.println("test2");
return this;
}
public Type3 gotype3() {
System.out.println("gotype3");
return new Type3<Type2>(this);
}
public void endtype2() {
System.out.println("endtype2");
}
}
public class Type3<T> {
private T parent;
public Type3(T parent) {
this.parent = parent;
}
public Type3 test3() {
System.out.println("test3");
return this;
}
public T endtype3() {
System.out.println("endtype3");
return parent;
}
}
public static void main(String[] args) {
new Test().run();
}
private void run() {
new Type1()
.test1()
.gotype3()
.test3()
.endtype3()
.test1()
.endtype1();
}
}
You can see in the .run() method that i start by creating a new instance of the Type1 class, which follows the builder pattern. At some point i'm calling the .goType3() method which transfers control to the Type3 builder. Because it has to return control at some point to Type1 again, a reference to that builder is passed via constructor to Type3. When it's time to return to Type1, the method .endtype3() is called. And here lies the problem. I'm using generics to (try) to return the datatype of Type1 but instead it's converted to an Object type. That datatype obviously does not have the methods that Type1 has and therefore the pattern is broken.
Question: is there some other way to return the proper datatype to the parent builder?
You're not using generics as much as you want to. You're using return type Type3. You need to use Type3<Type1>, Type3<Type2> and Type3<T> instead.
Thanks to Rob Spoor i got my code finally working, though i didn't understand it at first. The solution lies in changing the code in the following ways:
package com.example.fluent;
public class Test {
public class Type1 {
public Type1 test1() {
System.out.println("test1");
return this;
}
public Type3<Type1> gotype3() {
System.out.println("gotype3");
return new Type3<Type1>(this);
}
public void endtype1() {
System.out.println("endtype1");
}
}
public class Type2 {
public Type2 test2() {
System.out.println("test2");
return this;
}
public Type3<Type2> gotype3() {
System.out.println("gotype3");
return new Type3<Type2>(this);
}
public void endtype2() {
System.out.println("endtype2");
}
}
public class Type3<T> {
private T parent;
public Type3(T parent) {
this.parent = parent;
}
public Type3<T> test3() {
System.out.println("test3");
return this;
}
public T endtype3() {
System.out.println("endtype3");
return parent;
}
}
public static void main(String[] args) {
new Test().run();
}
private void run() {
// new Type1().test1().test1().endtype1();
new Type1().test1().gotype3().test3().endtype3().test1().endtype1();
// new Type2().test2().gotype3().test3().endtype3().test2().endtype2();
}
}
See the changes in the return types of the .gotype3() methods in the Type1 and Type2 classes, as well as the return type of the .test3() method. Now everything is working fine.
I have to use an 3th party library to create a java driven plc. in this library you have to define the IO's etc and then you will auto generate some code to acces the IO. this will generate a lot of code which i want to split up to keep readable.
The BIhcs_Io class is where everything on the event driven plc is executed. Each time a value of a property changes (see example below of property) it will run the doExecute() method.
What i want to do is that when this method is called, instead i want to execute it on the child class.
any help would be greatly appreciated!
public class BIhcs_IO extends BComponent implements Runnable {
//Example of a created property for a PLC IO
public static final Property bool_1 = newProperty(Flags.EXECUTE_ON_CHANGE | Flags.OPERATOR | Flags.SUMMARY, ((BBoolean)((BValue)BBoolean.TYPE.getInstance())).getBoolean(), BFacets.tryMake(null));
public boolean getBool_1() { return getBoolean(bool_1); }
public void setBool_1(boolean v) { setBoolean(bool_1, v, null); }
public static final Action execute = newAction(Flags.ASYNC, null);
public void execute() { invoke(execute, null, null); }
#Override
public Type getType() { return TYPE; }
public static final Type TYPE = Sys.loadType(BIhcs_IO.class);
public BComponent getComponent() {
return this;
}
public void started() throws Exception {
}
//When the Property bool_1 changes it wil execute the doExecute() method below
public void changed(final Property prop, final Context cx) {
super.changed(prop, cx);
if (!this.isRunning()) {
return;
}
if (Flags.isExecuteOnChange((BComplex) this, (Slot) prop)) {
this.execute();
}
}
public void run() {
System.out.println("Source BProgram did not override run(). Exiting thread.");
}
//This is called when a property changes value. When this is called, instead of executing this i want to execute the code in BIhcsMain()
public void doExecute() throws Exception {
setDebug_1("called parent")
}
public void stopped() throws Exception {
}
}
Below is the child class that extends the parent class. Each time the doExecute() in the parent is called i want to override it and execute the one in the child class instead.
public class BIhcsMain extends BIhcs_IO {
#Override
public void doExecute(){
setDebug_2("called child");
}
}
I have class three classes. Pref, ClassA, and ClassB.
public class Pref{
public static ArrayList<Pref> prefList;
public static Observable<ArrayList<Pref>> observable;
public static void loadData(){
prefList = getFromDb();
observable = Observable.just(prefList);
}
}
Application runs the ClassA First.
public ClassA{
public ClassA(){
initObserver();
setObserver();
}
public void initObserver(){
Pref.loadData();
}
public void setObserver(){
Observer<ArrayList<Pref>> obs = new Observer() {
#Override
public void onSubscribe(Disposable dspsbl) {
System.out.println("Subscribed");
}
#Override
public void onNext(ArrayList<Pref>> t) {
System.out.println("Loading Preference.");
//Need to do some other works here.
}
#Override
public void onError(Throwable thrwbl) {
}
#Override
public void onComplete() {
}
};
Pref.observable.subscribe(obs);
}
}
Now I want to change the list from ClassB.
public class ClassB{
private void changeList(){
Pref.prefList = loadDataFromSomeSource();
}
}
When I run ClassA, the System.out works fine. But when I change the list from ClassB nothing happens. My question is, is the right way to work with Rxjava. Is it for Rxjava built? If I am wrong how can I achieve this functionality? How can I write several ClassA like classes so that When the ClassB::changeList() runs, I can listen it in ClassA?
By setting Pref.prefList = loadDataFromSomeSource();, you assign a new list instance to Pref.prefList. This will not update Pref.observable in any way, because this still refers to the old Pref.prefList instance.
I also think that you can not use an Observable to publish events through it. As far as I understand your situation, you need an ObservableSource (see http://reactivex.io/RxJava/javadoc/io/reactivex/ObservableSource.html). For example, it is implemented by PublishSubject. You could use it like this:
PublishSubject<String> source = PublishSubject.create();
source.subscribe(System.out::println);
source.onNext("test 1");
source.onNext("test 2");
source.onNext("test 3");
Or, in your case: in class Pref, you can use public static PublishSubject<ArrayList<Pref>> source = PublishSubject.create();. When loading the data, you can publish the new data using onNext, like this in ClassB: Pref.source.onNext(loadDataFromSomeSource())
Consider a method
public void doSomething(String actionID){
switch (actionID){
case "dance":
System.out.print("I'm dancing");
break;
case "sleep":
System.out.print("I'm sleeping");
break;
default:
System.out.print("I've no idea what I'm doing");
}
The implementation of the method depends on the value of the parameter. Is there a more elegant way to do this, or a different design pattern to replicate the behaviour?
If the caller decides what logic is executed by passing different strings, then why not just have them call different methods:
public void doSomething(String actionID) {...}
...
doSomething("dance");
doSomething("sleep");
VS.:
public void dance() {...}
public void sleep() {...}
...
dance();
sleep();
It seems like you're unnecessarily funnelling all the calls into doSomething
But the strings might not always be literals. What if you're taking them from the console?
You could provide static mappings from the strings to the corresponding functions:
class MyClass {
private static final Map<String, Consumer<MyClass>> map = new HashMap<>();
static {
map.put("sleep", MyClass::sleep);
map.put("dance", MyClass::dance);
}
public void doSomething(String actionID) {
map.getOrDefault(actionID, MyClass::doNothing).accept(this);
}
public void dance() {
System.out.print("I'm dancing");
}
public void sleep() {
System.out.print("I'm sleeping");
}
private void doNothing() {
System.out.println("I've no idea what I'm doing");
}
}
This makes scenarios where you have a lot of switch cases a lot cleaner.
Introduce an interface, e.g.
public interface HumanState {
public void tellMeWhatYouAreDoing();
}
encapsulate the logic in different implementations
public class DancingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm dancing");
}
}
public class SleepingState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I'm sleeping");
}
}
public class UnknownState implements HumanState {
#Override
public void tellMeWhatYouAreDoing() {
System.out.println("I've no idea what I'm doing");
}
}
and use a map. E.g.
public class HumanStateExample {
public static void main(String[] args) {
HumanStateExample humanStateExample = new HumanStateExample();
humanStateExample.doSomething("dance");
humanStateExample.doSomething("sleep");
humanStateExample.doSomething("unknown");
}
private final HashMap<String, HumanState> humanStateMap;
public HumanStateExample(){
humanStateMap = new HashMap<String, HumanState>();
humanStateMap.put("dance", new DancingState());
humanStateMap.put("sleep", new SleepingState());
}
public void doSomething(String action) {
HumanState humanState = humanStateMap.get(action);
if(humanState == null){
humanState = new UnknownState();
}
humanState.tellMeWhatYouAreDoing();
}
}
I'm not sure how the pattern is called, but it is very useful if you need to delegate the method call based on more than one parameter:
Create a lot of handlers where each one knows when it is responsible for handling a call. Then just loop through them and invoke the first one matching the parameter.
edit: I renamed the class from FancyParameterActionFactory to FancyParameterActionUtility: it is not a factory, the name was misleading
//Your method, but this time with a complex object, not with a simple string.
public void doSomething(FancyParameterObject fpo){
FancyParameterActionUtility.invokeOn(fpo);
}
//The utility which can handle the complex object and decides what to do.
public class FancyParameterActionUtility{
public Interface FPAHandler{
void invoke(FancyParameterObject fpo);
boolean handles(FancyParameterObject fpo);
}
//Omitted: Different implementations of FPAHandler
public static List<FPAHandler> handlers = new LinkedList<>();
static{
handlers.add(new DanceHandler());
handlers.add(new SleepHandler());
//Omitted: Different implementations of FPAHandler
}
public static void invokeOn(FancyParameterObject fpo){
for(FPAHandler handler:handlers){
if (handler.handles(fpo)){
handler.invoke(fpo);
return;
}
}
//Default-Behavior
}
}
Here is a simple implementation of the command pattern based your sample problem. I define a general AbstractCommand abstract class which contains two methods. The first method, createCommand(), instantiates a command class based on an input string name. This is how you can delegate your string input to create the right type of command. The second method is doAction(), and this is left undefined, to be implemented later on by specific concrete command classes.
public abstract class AbstractCommand {
public static AbstractCommand createCommand(String name) {
try {
String clsName = name + "Command";
Class<?> cls = Class.forName(clsName);
AbstractCommand command = (AbstractCommand) cls.newInstance();
return command;
}
catch (Exception e) {
System.out.println("Something went wrong.");
}
}
public abstract void doAction();
}
public class DanceCommand extends AbstractCommand {
public void doAction() {
System.out.println("I'm dancing");
}
}
public class TestCommandPattern {
public void doSomething(String actionID) {
AbstractCommand cmd = AbstractCommand.createCommand(actionID);
cmd.doAction();
}
public static void main(String[] args) {
TestCommandPattern test = new TestCommandPattern();
test.doSomething("Dance"); // should print "I'm dancing"
}
}
Now that this framework has been setup, you could easily add other commands for the various types of actions in your original problem. For example, you could create a SleepCommand class which would output I'm sleeping, or do whatever action you wish.
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. ; (
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.
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);
}
}