Need someone to make a class to hold objects...

Discussion in 'Plugin Development' started by Jayjay110, May 24, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    Jayjay110

    I need to know how to get the block from say a block break event and use it globally, so i can use it in a timer, does anyone know of a simple way to do this, if not post ur genius :), I will credit you if I use ur code on my plugin Fridges :)
     
  2. If your using the bukkit scheduler then create a variable in that class like so :
    PHP:
    private Block block;
    Then create a setter, also in your scheduler class.
    PHP:
    public static void setBlock(Block b){
        
    this.block b;
    }
    Then on block break event on your break listener call the function.
    PHP:
    SchedulerClass.setBlock(event.getBlock());
    Also don't forget to check for null in your timer incase the player hasn't broken a block yet :D
     
  3. Offline

    DreadKyller

    you could make a hashmap in your main class and add the block to the hashmap, then just by using:

    public HashMap<Integer, Block> blocks = new HashMap<Integer, Block>();

    this.plugin.hashmapname.get(idnumer)
     
  4. Offline

    Jayjay110

    Im actually really retarded and dont know how to create a scheduler class... u got a tut like ur other good one :D

    this probably seems like the better option, but I dont know how would I save the block to a file?
     
  5. If you look on my tutorial at the zombies plugin source code you can see there ;)
     
  6. Offline

    garbagemule

    If you don't want to use get- and set-methods (understandable), at least make your fields "package-private", i.e. protected. Please don't use public fields, it's such bad programming practice, and it aches my nitpicky heart :(
     
  7. Offline

    DreadKyller

    @Jayjay110 :
    If you do not know how to save, look up @Adamki11s Mega Tutorial, it goes over saving and my favorite saving method, SQL Lite Lib by @alta189 either way, no matter which method you use, a class to hold all the objects, or a hashmap, you'll need to save it with both, cause it will not keep the info.
     
  8. Offline

    Jayjay110

    Why make the packages private, can other plugins interfere with the same named methods? Oh shit!

    What do you mean by, "It will not keep the info", isn't there any way to save the block data for later use? If not, how would plugins like LWC keep their chest positions? Do they just give a random ID number and xyz co-ords?
     
  9. Offline

    DreadKyller

    there IS a way to save, using SQL or writing to files, I'm saying no matter which you do, using a class or a hashmap, the data will NOT SAVE AUTOMATICALLY, not that you CAN'T save, look at the tutorial I sent you for SQL, then you'll know at least one way to save, but it will not do it for you.

    Also, package names will not interfere with other plugins, I have 6 plugins on my server that have the EXACT same name, org.styllex.main
     
    Jayjay110 likes this.
  10. Offline

    garbagemule

    I don't understand the need for sarcasm. I'm just offering a friendly heads-up in case any of you want to expand your programming horizon and venture into projects where the wrong access modifiers will give you problems. That's not the kind of stuff you will want to learn the hard way. Even if access modifiers seem redundant and irrelevant for miniature programming projects like Bukkit plugins, rest assured it is not the same case in the real world. Why not avoid the bad habits from the start? :)
     
  11. Offline

    nisovin

    Doesn't "protected" mean "accessible from the class or any subclass" and not "accessible in the same package"? In which case using protected wouldn't be useful if you need to access the class field from another class. You'd have to either declare it public or use get/set methods.

    Edit: Guess not... huh... TIL.
     
  12. Offline

    Jayjay110

    No I didnt mean it like that, that was prob my bad for bad english, I meant to say "Why make the packages private, can other plugins interfere with the same named methods? If so oh shit!" Sorry 4 the miss understanding lol
     
  13. Offline

    garbagemule

  14. Offline

    DreadKyller

    @garbagemule I always use public, or almost always, because I have a series of private plugins i;m working on that are dependent on each other, I have added them as external jars, if they were private I would not be able to access them. Also I don't mind if people would be able to use my methods and stuff, I guess it's all a personal preference, I wouldn't call it bad habits
     
  15. Offline

    garbagemule

    The main problem with direct access to fields is that if the data types aren't immutable (public String is okay, for instance, because String is immutable), but if not, then you risk not only corruption, but you have no idea what kind of manipulation might be going on. Leaving your mutable fields public carelessly, which is what a lot of people seem to do, is a bad habit.

    If your experience with programming doesn't exceed that of plugin development, it's only natural that you would go "nerr, big deal, what's gonna happen? Will people screw up their own server by using plugins that interfere with mine? Their problem, not mine", but consider making a database-oriented application for something like a bank. Access to bank accounts should never be direct. If you withdraw money from your account, you could call Bank.withdraw(50.00), and all you know is that the double variable holding your balance just went from 161.00 to 111.00. What you don't see is all the extra stuff going on inside of withdraw(), such as sanity checks, logging, etc.

    Now consider this plugin-related issue. Imagine you have made a plugin that logs all blocks placed by every player on the server. You store this data in a HashMap, let's call it blockMap, that maps every block to a player. You make blockMap public, meaning I can write a plugin that not only reads, but manipulates this HashMap however I want. I can remove keys, add keys, or even clear the entire list, because whatever you can do with that HashMap, I can do with that HashMap. Imagine now that, for some reason, you want your plugin to print the content of the HashMap, and expect a great list, but instead you get nothing, because some "enemy" has cleared it. That enemy could be an evil-minded person, or just someone who doesn't know what they're doing. Had you kept your field private and made accessor and mutator methods, not only could you control EXACTLY how the data is accessed and manipulated, you can also do comprehensive logging of everything.

    One of the four major principles of object-oriented programming is encapsulation - public fields means you're opening up your application and allowing anyone to manipulate the states of your program without you having any control over how it's done. And while it might not be a big deal for plugin development, it is, like I said, quite a big deal in the real world.

    Sorry for the long post, but when I say it's a bad habit, it's because it really is a bad habit. There isn't much to lose in plugin development, but imagine the kind of trouble you would risk in another situation.
     
  16. Offline

    DreadKyller

    @garbagemule : It is possible to do that, point taken, but now consider this point, the plugin that would allow access to the hashmap would have to be downloaded by the person using the server, if the host doesn't want that in their server they would not download it, and if they downloaded it then they obviously don't mind the part about people clearing the hashmap. On real projects, like important ones for like example games and such I can see using protected and stuff, but for a plugin? Use whatever you think is best, but I believe that if anyone edits any content of my plugin, the server host agreed to have that on their server, so if they not like it it's their own problem.
     
  17. Offline

    garbagemule

    Like I said, it might not seem like a big deal for plugins, but I assure you that plugins are the exception, not the rule. "That's their problem" is basically like saying "I know I am a bad programmer, and if any other plugins interfere with my plugin due to shortcomings in my code, that's not my problem." Why would you even consider such an attitude? All your needs are easily met by protected access modifiers, so there's no need to make them public.

    What I'm saying is that it's bad practice, and it WILL cause problems in real world applications. There's really no discussion to be had. It's bad practice, and if one has any sort of ambition to one day expand one's programming horizon past Bukkit plugins, there is no need to fall into bad habits just to have them shaken off later. Just learn to do it right the first time :)
     
  18. Offline

    DreadKyller

    dude, first off you are extremely rude, my point is, if the host of a server downloads a plugin which has access to another plugin they A: want it, or B: don't care. You use whatever you want, but stop trying to force others to do it the same way. Imaging this scenario, are you going to tell TheYeti to not use public? If so then there would be no plugins made with permission support. Also to tell you I'm a video game designer, I not only work on plugins but am almost done with an mmofps game, I know about safety with scripting, but for this purpose it is not a necessity and can not be forced, stop demanding it from people and acting like you are the maker of the scripting language. In REAL WORLD applications yes, you should use protected and private, but for this, using proteccted, public, or private don't make a ** bit of difference.
     
    Adamki11s likes this.
  19. Offline

    garbagemule

    I'm sorry if I come across rude. That was not my intention. It is, however, well established that public fields is a no-no, because it breaks encapsulation and thus violates one of the four major principles of object-oriented programming. I'm just giving a heads up, like I said, because it IS a big deal elsewhere. There's no need to repeat what I've already said. I think we agree that it doesn't make much of a difference here, but since when is offering good advice a crime?

    Oh, and anyone can call themselves a "video game designer". Heck, I can call myself a politician or a kangaroo if I want. It doesn't change the fact that I don't know anything about running a country or traveling at high speed by jumping. I wrote a bunch of small games and programs when I was 16, too, as I'm sure a lot of people on here did. I'm sorry you're taking such great offense from this, but there really is no need to act up like this. If you saw a friend of yours eating soup with a steak knife, wouldn't you advise him to use a spoon, so he wouldn't end up cutting his cheeks later on down the road? I'm not trying to "force" anything here. I'm saying it's bad practice, and those aren't my words :)

    Edit: I highly recommend the book Object-Oriented Design and Patterns (2nd edition) by Horstmann. It is very thorough and very easy to follow. Chapter 3 is very relevant to this topic, and there's a whole section on the importance of encapsulation. It also introduces a bunch of the more common design patterns that are relevant to pretty much any kind of software development.
     
  20. Offline

    DreadKyller

    lol, yeah, it's actually sort of funny that I post that and then when my page refreashes I see you have already sent me a pm..., I'll delete the post... not much use for it.
     
  21. Offline

    Jayjay110

    hmmm, U all lost me once ur post went over 20 words :3 I really dont even know what a public or private PACKAGE is, only methods lol... anyway im not coming back to this thread anytime soon

    /thread
     
  22. Offline

    DreadKyller

    ok @Jayjay110 : I just got a pm from garbagemule and what he's talking about is public fields, like some people use:

    PHP:
    public MainClass plugin;
    public 
    ThisClass(MainClass plugin){
        
    this.plugin=plugin;
    }
    he is saying that methods can be public, but the fields should not, like plugin should not be public:

    PHP:
    private MainClass plugin;
    public 
    ThisClass(MainClass plugin){
        
    this.plugin=plugin;
    }
    the example he gave as to why this is a bad practice is imagine there is a plugin that is made dependent on the field, and not the method, if the field name, type, or publicity changes then the plugin will not work until updated, when the method can be still used because most likely it was changed to work with the new name or whatever the change was.
     
  23. Offline

    Jayjay110

    How would the name, type or publicity change?
     
  24. Offline

    garbagemule

    The rule of thumb is "once public, always public". If your code is in any way used by others, anything that you have made public should remain public in future updates, because if you change anything public, it might have severe side-effects in software utilizing your code. "Not my problem" will get you fired in the real world.

    Consider a public Set<Player> "players". For your initial purposes, the set is sufficient, because all you're storing is a bunch of Player objects. You let users of your code access the field directly, meaning they can manipulate it however they want. Later, you realize your set isn't good enough. You want to, for whatever reason, associate an integer value to each player. So you change players to Map<Player,Integer>. Anyone using Set-specific methods to access your public field is now forced to change their code. They can no longer simply say players.contains(p), but have to change their code to players.containsKey(p). Furthermore, they have to change all of their players.add(p) to players.put(p,?), where ? is a value whose importance they may not know.

    Consider now the private Set<Player> "players". To access this from outside, you create a public method in your class called containsPlayer(Player p). The only thing this method does is return players.contains(p). To add and remove from the outside, you further create public methods addPlayer(Player p) and removePlayer(Player p). Now comes the point when you realize you could do with the associated integer values, so you change Set<Player> to Map<Player,Integer>. So obviously, you will now have to change your accessor and mutator methods. containsPlayer(Player p) now does return players.containsKey(p) instead, but the users of your code don't have to know that. They still just call containsPlayer(p) from their code. You then change the add and remove methods to e.g. players.put(p,1) (or any solid default value) and players.remove(p).

    This is just one really simple scenario, but overall, accessors and mutators allow you to control exactly how people use your code and access your fields. You can even perform sanity checks within your public methods, making everything a lot less prone to errors. Like I said in the beginning, public fields are simply just bad practice, so try to avoid them (for your own sake) if you can, if you plan on doing something a bit more involved in the future :)
     
    DreadKyller likes this.
  25. Offline

    DreadKyller

    @garbagemule with the map.remove() you only need to key, not the value.
     
  26. Offline

    garbagemule

    Haha, thanks. That's the problem with copy/paste :p
     
  27. Offline

    DreadKyller

Thread Status:
Not open for further replies.

Share This Page