Hello, I decided to become a member because about 75% of the time when I search for resolutions to my problems, I find the right answer at CodeRanch.com so I thought, I want to be part of that. Just wanted to thank you for that and point out that the knowledge on this forum does not go unnoticed. Onto business...
I am new to the application develoment world using Java or any OOP language for that matter so I need some pointers on my current task. (I have extensively used AutoHotkey but it's not as robust as I get into more advanced features, especially in dealing with MySQL).
I want to redevelop an application that is used to view current RMAs in our service department. It is used as much more than that but that is the general premise. I would like to use this thread as a sort of walkthrough and continue to post progress updates as I redevelop this application. I don't know anyone personally to help me with this.
Here is a very basic step by step of how it works:
1. Startup - Checks database for user preferences (specific product to filter on, specific depot to look at (this is a global application and each depot has different products), other settings)
2. If there was a product/depot in preferences the application automatically will run a sequence of queries and put that data into a series of tables, otherwise it will wait for the user to select a product/depot
3. Every minute, the program checks the update time of the table in the DB and updates if needed
Here are my thoughts on the structure and this is where I would like some help because I am new to OOP.
MySQLConnection class - creates a java.sql.connection and will execute queries (I am currently writing this and will post code below)
MainGui class - This will be the guts, it will contain the GUI and all of the ActionListeners and related code
Depot class - contains depot information
Group class - multiple products belong to one family which then belong to one group
Family class - multiple products belong to one family
Product class - hold information about each rma
I am sure there will actually be many more classes than this but this was my first idea of how it would be laid out. Suggestions, ideas?
Here is my MySQLConnection class which I am currently working on. What I'm having trouble with is the executeQuery(String query). I would like to have it decide whether the statement will return data (SELECT) or if it's just an UPDATE, INSERT, ... and then call one of two private methods. Would this be a good idea or should I handle the Query execution in the MainGui class? Also, if this method is a good idea then should I have a statement variable for the class to be reused or instantiate a new statement for each sql executeQuery() call closing it after each call?
Not sure if this really belongs in the JDBC section or in the beginning Java section, I will let someone else decide that...
What you are asking is basically if your design would work. I can only start out with these simple tips, hopefully this will help. This is not easy to answer in my view.
1) You will want to keep your UI (Swing) code separate from all others. For instance, an SQL class should return a type of error but not actually display it using Swing. Don't mix responsibilities.
2) Your classes mirroring the entities in the DB are what are called bean classes. They should be simple data carriers with getter and setters. Some people argue about this point, at least for a beginner makes sense. Since they are data carriers they should have no other logic.
3) Next you should have a database access classes (often called DAO or data access objects) that handle all the database interaction. They create and return single objects from #2, or arrays or lists of them. They know how to create, read, update and delete (CRUD) data.
4) Next you have some service classes that use the different DAO classes to perform the actual logic in your application. They are the middleware between your GUI and your DAOs. They would have methods like . Note that services can use other services also.
5) Finally your have your UI code that takes user input, calls out to services and gets the bean classes (from #2) and knows how to display them. It doesn't have any other logic, just the user interaction.
I hope this answer made some sense and will help you organize your application. Build it a little bit at a time and in an iterative fashion, testing often and you should be able to keep the complexity under control.
I too struggled with whether or not this was Beginner or JDBC but I opted for JDBC since it included it in the discussion. After I posted it I kind of felt that I was looking more for instruction on the structure as you provided.
The information is helpful, I have not dealt with Beans yet other than in a sample JSP, I was trying to avoid them because I hadn't learned about them in school and when I brought it up in one of my classes they said, we don't deal with beans here in a derogatory way like beans were a bad thing. (It was a Data Structures class so maybe that had something to do with it).
The information you provided was helpful, I am trying to do as you said, keep the entities in their own classes but it's tough to figure out. Everywhere I have looked there doesn't seem to be a clear cut structural design. I look at samples in books but they always have all of the code in one class which is NOT what I want, yuck! This program is currently over 100 pages long and I figure it will be at least three times that when I'm done converting it so it definitely needs to be broken up into an intelligent, easy to maintain structure.
I have trouble deciding when a new class should be made, for instance, I am creating the GUI class, it has five tabs, I was thinking of creating a class that extends JPanel for each tab and then the main GUI class could just say
Is that logical? There are quite a few components on each tab so it's confusing having it all in one main class.
This probably does belong in beginner, only a portion of this is going to pertain to JDBC. Can I have this moved?
Yes, absolutely - make each tab it's own class. When in doubt, err on the side of having more classes. Since a tab is usually a container for other UI controls, each of your tab classes should be a JPanel (ie, it extends JPanel); even if it contains just 1 control today, make it a JPanel.
In addition to the great advice given above, here are some more suggestions:
1. Identifying classes: What should be a class, is a problem I think all of OOP learners in every language face when starting off (atleast I did).
A good way to find out classes is to write a textual description of how to achieve each user end goal in your app, and then look for the nouns in that description.
This is called Noun analysis (one more tutorial here).
It's a good technique for OOP beginners to find out classes. Good news is, with practice, this comes naturally.
The idea is, write the descriptions in simple terms, not technical terms - like you're explaining to another person. Then look for the nouns.
An example: "For creating a new inventory order, user should open the inventory management window, select the new inventory page, fill the fields on that page, and save inventory. System will validate the fields, and save the new inventory in inventory database".
Nouns (and potential classes): Inventory, Order, Inventory management window, Inventory page, Validation, Inventory database.
Such analysis will never give you all classes (because things like code reuse and abstractions are programming concepts and not everyday speech concepts), but it'll give you most of them.
2. Packaging: Split your app into at least 4 layers in terms of packages (this is one way of splitting. Another way is to split first by function and then create model-view-controller-data subpackages under each function - this is suitable for large apps where each function is sufficiently independent of other functions).
com.yourapp.model - contains all bean and business logic classes
com.yourapp.view - contains all UI (Swing) classes and related classes
com.yourapp.controller - this I'll explain next point
com.yourapp.data - contains the DAO and persistence management classes
3. MVC architecture: Follow the MVC (Model-View-Controller) architecture for each and every user end goal that your app caters to. This is a great architecture for desktop apps like yours, and it keeps your app flexible enough to meet UI requirements in future.
In MVC, for every goal ("use case" in technical terms), atleast 4 classes should collaborate:
The "Controller" is a class that is like a director for workflows - it directs the steps of the goal in the required sequence and coordinates between the UI and the logic. The advantage of having a controller is that if app executes same action for different UI elements (ex: Save in menu, and Save button in toolbar), then code need not be repeated in each action listener.
The "Model" is a class (or more usually a set of classes) that is/are responsible for business logic. This set consists of bean classes and service or business logic classes.
The "View" is a (set of ) class(es) that is/are responsible for creating the UI elements, listening to user actions, showing error messages.
The "DAO" or data classes are responsible for saving and reading data from a persistent store (a JDBC database in your case).
The collaborations among MVC classes all follow this pattern:
1) User does some action (clicks a menu, clicks a button, etc)
2) An action listener in the view class(es) receives this action.
3) The action listener calls a method in its respective controller class, that sets off a sequence of processing actions
4) The controller may ensure some preconditions (for example, before creating a new request, inform one or more UI elements to disable themselves until processing is finished; or check that some other processing that may lead to data inconsistencies is not running).
5) Controller delegates the processing to a class in the model layer.
6) The model does some processing using its business logic.
7) The model informs a DAO class in data layer to persist to /read from database.
8) Model may populate some beans which contain information read from database, to be displayed back to user. Or it may contain error information if there was an error.
9) Model can now directly notify a view about results or errors using the Observer/Listener pattern, or it can do so via Controller by returning beans back to Controller.
10) If model returned data to controller, Controller passes it along to the view to be displayed.
11) If the last action resulted in some fatal error, then controller can inform all other components to cleanup (like closing DB connections) and finally exit the application.
4. Sequence diagrams: Another good tool to think about flows in your app (ie, which class should do what?) is to use sequence diagrams to find out methods and responsibilities (especially for business logic classes). A simple tool you can use for creating sequence diagrams is http://www.websequencediagrams.com/
5. OO axioms: There are many other good axioms in OOP - code to interfaces and not implementations(especially true for service classes); even if current requirements require just 1 object
of a type, code in such a way that in future n objects of that type can be handled, etc, etc.
But the best way to understand why these axioms are priceless, is to not follow them at all the first time! It's hard to explain why you should follow them, if you haven't experienced the problems of not following them and doing OO wrong. So consider these axioms only in your second stage of learning OOP.
6. Starting off: To start with, follow all these principles for completely implementing just one use case - that itself will throw up lots of issues and questions. Get that single use case implementation reviewed by a colleague - they will, for sure, tell you some UI changes ("I'd like this to be a table, not a list!"). Try incorporating those changes - that'll throw light on which parts of your OO design and classes are not flexible enough at the moment. The goal of OOP is flexibility.
7. Avoid paralysis by analysis: Lastly, I think it's very easy to end up in a Paralysis-by-(OO)Analysis situation for beginners. So think up one way of framing classes using the broad principles mentioned above, don't worry if it's THE complete and perfect design - there's no such thing, jump in and implement that design, it'll have some problems for sure, then solve those incrementally by refactoring.
WOAH!, this is why I joined coderanch. This information is EXTREMELY helpful. I can especially relate to the last comment about paralysis. I keep starting to implement something and then it seems like, even though I planned it out, something wasn't accounted for and it isn't going to work and I stop. It's nice to see that these issues I am facing are normal for a beginner OOP.
I will use this information and I will definitely just get a simple use case to start with, then I'll come back for more Q & A. Thanks a lot, very informative and very helpful information.
Geoff thanks for Asking. I hope you don't mind that I ask this add-on question in you thread.
Thanks your reply was what I have been looking for all day. I am suffering from Paralysis-by-(OO)Analysis
and was hoping you could guide me one step further in my 1st JDBC/swing application.
Due to my requirements I am using JDBC without entity binding and have a predefined database and classes that map to the tables.
I have used Netbeans to create my swing layout and am now starting to glue things together using the MVC design pattern.
Given this framework I am at a loss as to where in the calling structure I should be instantiating my model/DAO/ and controller classes
My gut say in main but the constructor of the view is also calling me.
I can't seem to ask Google the correct question and all of the source I have reference either:
1. Show JDBC without swing
2. Swing without JDBC
3. Show JDBC with swing using JPA which I believe is called entity binding.
Since my database and classes are predefined I cannot use the third choice which appears to be the modern approach.
Hi Terry Harple, can you post your question as a new discussion thread so that it benefits other people searching for the same issue, and perhaps get more opinions too? I can tell you how I instantiate them, but I feel it would be better to do so in a new discussion thread since this is a separate question.