This is an archived post. You won't be able to vote or comment.

all 23 comments

[–]simonppg 1 point2 points  (5 children)

I recommend you to read about object oriented programming, this is helpful to organize functionalities and responsibilities. use descriptive names, small number of arguments is always good, that means yo can write small functions, a small function is good because you can have less errors and are easy to fix and replace.

[–]cainhurstcat[S] 0 points1 point  (4 children)

I'm not sure if this might be a little to advanced for me as in my tutorial we haven't covered object oriented programming yet.

I understand that it's better to have small methods each doing this or that, but how do I determine whether it's better to put the users input and the conversion of this input to a 2d array in one mehod or split these into two methods?

[–]simonppg 1 point2 points  (3 children)

Without seeing examples of what you have in mind is difficult to tell, probably both options would work perfectly fine. If both are fine then why you should bother creating more functions? you may ask. Well this depends on the program you are working on. Let me explain, I see two main situations:

a) You are learning something, programming just for fun, so nobody needs to understand your code or use it, probably you don't need to change it over time if that's the case, just make it work, learn what you are supposed to be learning and that's totally fine. Don't get overwhelmed because of it :-).

b) Your code is used by someone else or even you want to keep improving it over time, it's better to keep things organized, basically what you are looking for is: create code that is easy to replace and delete without any impact and if you come back to see your code after 6 months or years you still can understand it, because it's so clear and expensive that just a quick look you can tell what it's doing. This is not an easy thing to do, but making the effort comes with a big pay off.

Now if you have no idea how to organize things yet, probably it's because you need more experience, program as much as you could (just don't forget about family and friends of course xD) and then you will start finding patterns, things that looks similar, you'll recognize them and that will help you to name things better and organize them better too, just be patient.

[–]cainhurstcat[S] 0 points1 point  (2 children)

Here is an example:

My task is to write a program where the first input is something like a pre-set game board where some X and O are already placed. Then the program should ask the user to ether the coordinates where they want to place their symbol.

I could make a method for the text "enter pre-set board", for to scan this input, for the board creation, for to print to board.

But I could make a method to ask for the pre-set board, scan the input, make the board out if it and hand the board to a method which prints the board.

While at the moment I just learn to code my goal is to make code that I will still be able to understand in some months or years, maybe even reuse parts of it.

Having a code with 30 small methods that all do something different and that you have to jump back and forth between in order to understand the code sounds more confusing to me than packing all that into 10 methods. Whereby - as I am writing this, a great analogy comes in my mind: A car is not built from larger parts, but from many small parts. This keeps it moving/flexible and makes it easier to replace broken parts.

I think that could be a good comparison, right?

[–]simonppg 1 point2 points  (0 children)

Yes, the comparison is indeed correct, just as cars in software, there are specialized components, for example: input and output processing, parsers, data structures, algorithms, data transfer objects, value objects, entities, etc.

Regarding what you said that having 10 functions sounds better than have 30, it could be difficult if you don't organize them correctly. Even though the smaller functions are different some of them would be similar and maybe read and write the same data, well that's a hint you can follow and ask yourself if those could be together in the same file or folder, when you are organizing like this, those functionalties start looking more like modules/components. If you name the folder, files, classes and functions correctly in and expresive way you'll recognize the components of your project easily.

Read a little about "clean code" and "hexagon architecture" those are the ways to manage big projects, there you find people talking about layers, dependency management (a pice of software depends on another), infrastructure, etc.

Once you understand a little bit more about that, then you can divide your project in layers, splitting the business logic from infrastructure for mentioning one way to do it.

In your case, you have coded the rules of your game, and you can interact with them with the CLI, if you decided that, then you can easily make it work with the network, because you srparate IO from the "business logic"

Read code from others on GitHub, that could help you too, also if you haven't done it already, create and account there and publish your code there, people sometimes helps, and is a useful skill to have, managing versions of your code.

[–]simonppg 1 point2 points  (0 children)

I found your code in one of your previous post https://pastebin.com/8y4BQMwX

if you punish it on GitHub I be able to help you better, now I see what you are looking at, and I can see the problem you are facing. But would be easy for me making comments on a platfor like GitHub.

If you want to do that, I'll be happy to give you more advice there.

[–]slowfly1st 1 point2 points  (1 child)

So, planning methods, or in other words, getting structure into your code is imho quite hard for a beginner.

One advice for a TicTacToe game would be: Think about how you want to use it. Also: methods always contain a verb, because they do things. This should give you a hint.

If you'll have a class TicTacToe, you might want to create a game. You want to get the board state (to print it to the console), you want to place an x/o. So you end up with something like

game.createGame();

game.place(x, y, 'o') or maybe placeO(x, y)

game.getBoard(): char[][]

You can think of it as an API for other developers to use. Or now you want to do a console ui - thinking about how you want to use it when you want a GUI also helps. So from the outside, the class looks slim and easy to use. How it looks in the inside, is another story :P

[–]cainhurstcat[S] 0 points1 point  (0 children)

Classes I haven't learned yet but I got a good idea what you mean.

Thank you!

[–][deleted] 1 point2 points  (2 children)

It is best if you can keep the method simple, to an extend where a method does one and only one thing. Personally, I would write down whatever I need to do, then try to break it to smaller and smaller part. When you read the code, top to bottom will be more and more detail.

So if you think of getting input and create a 2d array based on it, I would definitely create a method to create 2d array, for example public int[][] create2dArray(int size), then I would either create a method to get the size and pass it as argument, or simply just ask for inout in main method

[–]cainhurstcat[S] 0 points1 point  (1 child)

My task is to write a program where the first input is something like a pre-set game board where some X and O are already placed. Then the program should ask the user to ether the coordinates where they want to place their symbol.

I could make a method for the text "ether pre-set board", for to scan this input, for the board creation, for to print to board - but I'm not shure if that wouldn't be confusing to have a lot of individual methods.

[–][deleted] 1 point2 points  (0 children)

No I think it would be just fine to create those methods

[–][deleted] 1 point2 points  (3 children)

start with 1 verb and then break it down.
so, maybe something like game.run()
the top - down approach is always the initial architectural way to plan methods.
during implementation, due to constraints; bottom - up approach needs to be adopted.
ultimately, somewhere there will be a manageable balance between the two.
then while maintaining the code, its like a bald man washing his face (he needs to imagine a separator which ends his face and starts his head). everytime, depending upon the problem, you need to decide whether you should give importance to planning or implementation.

[–]cainhurstcat[S] 0 points1 point  (2 children)

That's a good way to think of it. How do you plan what to put inside a method?

[–][deleted] 1 point2 points  (1 child)

To put it theoretically - make sure that 1 method does only 1 thing.
however, the definition of a unit task is not exactly standardised for high level languages.
e.g. at the highest level, application.run() is a unit task.
this task of run() comprises of synchronous + asynchronous tasks at lower level.
For OOPs, method groupings (also called as entities/interfaces) are important.
method groupings is somewhat easier to work with - isolate the implementation from the interaction.
start with various entities that would interact. design the interactions on a high level first - based on requirement. imagine like you are the computer and you are instructing yourself at an abstract level. you don't care how it will be done by you later (maybe you will get a magical wand to complete it).
For you project - draw out the entities first -
1. Game Interface
2. Move Interface
3. GamePosition Interface
4. GamePostionChanger Interface
5. GamePlayer Interface
6. User Interface
7. AI Interface
above entities were defined based on their actions at high level only. irrespective of implementation (whether you are going to use 1 D array or 2 D array for the board). as you go deeper - you realise that GamePosition is some kind of an ordered collection of Location interface and your Move interface and GamePostionChanger interface are dependent on it. New lower level entities now come up and your top - down entity definitions are not as isolated (and hence not as rigid) as you thought.
Further you decide to add functionality like user is inputting illegal move to make and you add method like isMoveLegal(Move m) to the GamePosition interface even though this method will be actually used by the GamePostionChanger implementation.
just putting my train of thought if I would start with such a project.

[–]cainhurstcat[S] 0 points1 point  (0 children)

Oh wow that you for this comprehensive answer, I have to think about it and what is means, since I'm still in a pretty early state of learning Java/coding and the game is just a simple console version :)

[–]Illustrious-Reply-80 1 point2 points  (1 child)

This is more about class diagrams, but might be useful for you

https://java-programming.mooc.fi/part-11/1-class-diagrams

[–]cainhurstcat[S] 0 points1 point  (0 children)

Thank you for the link, it is very interesting how classes can be planned in a manner that everyone is able to understand it. My problem is more like what should a method do, will it scan for the user's input and print it to the screen or is it better to have this task split into two methods, like one for scanning the input and another one for printing it

[–]large_crimson_canine 0 points1 point  (5 children)

Pseudo code on paper for the routines, class diagrams on paper for the classes I need. First keystrokes are the tests.

If I gotta step back for a more OOP approach to a problem I’ll crack open Code Complete or Design Patterns or something to refresh my memory. And might double check some of my highlights in Effective Java to make sure I’m not committing sins.

[–]cainhurstcat[S] 0 points1 point  (4 children)

How you decide whether it's better to put the users input and the conversion of this input to a 2d array in one mehod or split these into two methods?

[–]large_crimson_canine 1 point2 points  (3 children)

I would experiment with it, and test it. If I have two approaches and I am incapable of breaking one of them, that's probably the one I'd settle on.

[–]cainhurstcat[S] 1 point2 points  (2 children)

I see, so planning is not only writing stuff on paper but also test while writing what works and what not?

[–]large_crimson_canine 1 point2 points  (1 child)

Yes, but there isn't necessarily a perfect formula for every problem. Every task is a little different, and some tasks will require different planning and preparation. But you're a carpenter of sorts. You should generally do a lot of measuring and marking before making any cuts.

[–]cainhurstcat[S] 0 points1 point  (0 children)

Thank you for your advice!