slazter Posted August 4, 2017 Share Posted August 4, 2017 Hey guys, im back again. So since my last thread in this part of the forums https://osbot.org/forum/topic/126653-trying-to-make-banking-class-errors/ i've taken the advice and started to read up on OO practices and design patterns. So the first pattern in the book Head first - Design patterns which im currently reading talks about the "Strategy Pattern". Simply a pattern to encapsulate what varies, code towards supertypes/interfaces and not towards implementation, aswell as using Composition, rather than Inheritance. So i made a couple of simple Strategy patterns with System.out.Println's. and it all worked well, however now when i try to apply my newfound abilitys to try and make something of it, mabye an AIO-Agility to learn good OO practices i get stuck, I get a nullPointerException - even though im pretty sure it's not like the last time, since this time I extend MethodProvider aswell as pass the bot with exchangeContext(bot). So anyways i'll post the Scripts, and mabye you guys can help me figure out where i went wrong, Since i know i could just use a single class that extends MethodProvider, then use exchangeContext on a reference variable of that class, but that wouldn't really help me benefiting from pattern designs, so anyways heres the codes: Main Agility script, This one is gonna be the main class that all the courses inherits from, atm no other methods, since i can't get first to work, but probably some eat(), pickUpMarksOfGrace() etcetc.. Also atm i don't need to extend MethodProvider, but if i have a eat() method, im gonna need it, therefore i extended it, unless im supposed to compose this entire Script then i guess i don't need to extend it. package Agility; import org.osbot.rs07.script.MethodProvider; /** * Created by Martin on 2017-08-04. */ public abstract class Agility extends MethodProvider{ //HAS-A Interface, so we can use composition IRunToCourse runToCourse; //delegates the runToCourse so char run to Position public void executeRunToCourse(){ runToCourse.runToCourse(); } } Interface, so i can use Composition, rather then coding to an implementation. package Agility; /** * Created by Martin on 2017-08-04. */ public interface IRunToCourse{ public void runToCourse(); } Class that implements IRunToCourse; I,e where the method is for doing this type of runToCourse, might have another for RunToDraynor, RunToAlKharid etc - thinking these could be nice, as i guess i could reuuse some of these classes and interface in other scripts that need the same spots aswell. anyways heres the code: package Agility; import org.osbot.rs07.api.map.Position; import org.osbot.rs07.script.MethodProvider; /** * Created by Martin on 2017-08-04. */ public class RunToGnomeCourse extends MethodProvider implements IRunToCourse { @Override public void runToCourse() { //Teletab to Cammy getWalking().webWalk(new Position(2461,3382,0)); //manage dialogue for doors //Walk to Course } } The GnomeCourse Class, ie the subclass of Agility, to do what's needed for doing GnomeCourse, needs the runCourse() obviously, but not sure if best as composition or inheriterd methods so only one thing in constructor so far. Probably gonna have DraynorCourse, AlKharidCourse, VarrockCourse etcetc... package Agility; /** * Created by Martin on 2017-08-04. */ public class GnomeCourse extends Agility{ public GnomeCourse () { runToCourse = new RunToGnomeCourse(); } } and then obviously the last part of the Design pattern, the script that makes all this run, the one that extends Script, this would be the AIO script, where a GUI could popup and ask which course etc.. package Agility; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; /** * Created by Martin on 2017-08-04. */ @ScriptManifest(author = "Slazter", name = "AgilityTest", version = 1, info = "", logo = "") public class AIOAgility extends Script { Agility gnomeCourse = new GnomeCourse(); public void onStart(){ gnomeCourse.exchangeContext(bot); } public int onLoop(){ gnomeCourse.executeRunToCourse(); return random(200,300); } } I know i could script to work with: RunToGnomeCourse runToGnomeCourse = new RunToGnomeCourse(); runToGnomeCourse.exchangeContext(bot); runToGnomeCourse.runToCourse(); But this would just defeat the entire purpose of Composition. So any clues why nullPointerException with the previous scripts that i Posted? It's just a single method im trying to do. Also any input regarding if this is a good practice or if i should look into another designpattern? Quote Link to comment Share on other sites More sharing options...
Final Posted August 7, 2017 Share Posted August 7, 2017 The design pattern is fine. The way you are implementing it is poor, however. You should have a parent class 'Course' and then subclasses such as GnomeCourse, then have your script hold a collection of 'Course' and initialize them before the script begins. The way you are currently structuring your OO makes 0 sense. Quote Link to comment Share on other sites More sharing options...