Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm making a customer administration software. There are several JPanels with much content on it, constantly communicating with a database. In the database is customer data, products etc.
For a faster access to the database data, at first I load it all in its own ArrayList, e.g. ArrayList<Customer>. If the user changes this data, it has to be changed in both the class and the database.
As the JPanel View looks very "full" (crammed with other JPanels and JTabbedPanes, switching through with the CardLayout), I thought it would be better to create an own class for every "main" JPanel and link them all with View.
For example an own class for the JPanel Customer, where all the customer data can be seen and edited, the same for products etc.
Does is make sense or is it inconvinient? I only want to do so to outsource the code and to make the classes clearer, especially View.
Is there something like a design pattern dealing with this problem?
So your program consists of a single class that subclasses JPanel and that contains references to all other components used in your UI? And you want to know if you should break out portions of that UI into other classes.
In short YES. You can always decompose any class into aggregated classes by moving portions of that code out into a new class, and have the original class contain a reference to the new class. This is called delegation or Extract Class refactor. You can read about this technique in Martin Fowler's Refactoring book.
Creating other UIs that are parts of the total UI, like CustomerPanel, is a good way to think about it. By doing this you can also decouple parts of your UI. Be careful when you create these smaller classes to move all dependencies to the new class. If you feel like passing a reference back to the main UI to the aggregated class then you probably haven't fully decoupled your classes. That should be a sign either you haven't given enough responsibility to the class you are extracting, or there is some other dependency they should be sharing.
Basically the rule is if you extract a class, it shouldn't have a reference back to the class that contains it. References should be more of a tree than a graph. It's ok for them to share a model class, but its not ok to create cycles between views.
You probably would find this interesting:
GUI guidelines for swing
I am not sure if I understood your intent, but looks like you want to achieve the level of decomposition which will allow you to outsource certain UI components and reuse them, well, basically achieve as lower coupling as possible. Apart from what #chubbard said, I would suggest you to look into MVP pattern and use event-based interaction between components rather than referencing them. This can eliminate unwanted dependencies and bring more reusability.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 days ago.
The community is reviewing whether to reopen this question as of yesterday.
Improve this question
I have a simple ATM system implemented in Java using Swing (I know Swing isn't really used anymore but I wanted it to be simple). The way I implemented it is as follows:
I have a Customer class which holds information about a customer and has a login() method
I have an Account class which holds information about an account and has methods for withdrawing, depositing and transferring money
I have a Transaction class which holds information about a transaction and has a generateReceipt() method that creates and exports a PDF with transaction info
I have an ATM class which holds the logged in account and the corresponding customer and has static methods for getting transactions, such as the current account transactions
Finally, I have an Admin class with username and password as attributes and methods for getting all the customers and accounts, adding a customer or creating an account and deleting a customer or an account.
My application uses a MySQL database for storing information and making updates. Also, customers can have multiple accounts and one can log in the system using the account number and PIN.
I drew the use case diagrams, and the class diagram, not considering my UI in the class diagram.
I have a hard time creating sequence diagrams for this application, as all my classes and objects are used in classes made with Swing.
My question is: how should I structure my sequence diagrams, considering the fact that it is a Swing application? Should I add the UI classes or should I make it more conceptual and only describe the process and relations between my other 5 classes?
Any help is highly appreciated!
I tried separating as much logic from the actual UI, but I still can't figure out how should my sequence diagrams look, as a customer and the admin interacts with the Swing frames.
The class diagram without any of the app's internals is a "domain model". Its goal is not to document all possible classes used in your apps, but to focus on the domain knowledge, independently of how the app is implemented. The diagram would stay the same if you had a real ATM device, if you would implement a web service, or if you would use any other UI framework.
So you made a clear choice on what you wanted the diagram to show. You could perfectly have chosen to have monstrous class diagram including in addition the classes required for the business logic, for database interaction and for the UI (e.g. using the famous Entity Boundary Control pattern). The diagram would then be more dependent on your implementation choices.
For the sequence diagram, it's the same. There is no best way to draft this diagram. The question is only about what you want this diagram to focus on: do you want to model the domain logic ? In this case you would use your domain classes and show how they interact. Or do you want to model the detailed application design , in which case you could envisage to add also UI classes. But the diagrams would then quickly become very complex, and you'd better break them down into several simpler SDs, each focusing on some parts of your detailed technical design.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I have had similar cases in the past, and this is just an example to illustrate:
I'm going to implement a new feature in my android app (but this applies to any kind of OO project), and at this point I need to implement some "action" in the "setVisibility" method from EVERY edittext in EVERY activity I have.
To do it, I have to subclass "EditView", and override "setVisibity" method:
#Override
public void setVisibility(int visibility)
{
super.setVisibility(visibility);
// --> do my stuff here! <--
}
So far, so good... the problem is to change all activities I have (more than 200, and thounsands code lines), and then I think: "why on earth didn't I start the project subclassing the standard EditText, 'cos I knew some point I'll need to implement something like this".
That's the point: Is it bad OOP to subclass a "standard class" into a new one that does exaclty same thing, but just "presuming" cases like that? I mean, subclass everything, like buttons, activities, etc.
AFAIK, desing pattern and OOP discourage the "presuming factor", but I'd to hear what you guys "do in real life" (or think about that), based on your programming experience.
Also, maybe this type of question ("what you think", "what your oppinion") isn't a good practice here in SO, but I can't find any better place to put it on.
There's no reason to stub out code unless you're actually making changes. It's wasted effort, and just bloats your codebase.
If you find yourself in a situation where you're repeatedly making the same modification, consider refactoring to share common code. Or in certain cases, there's merit to generating those pieces of code (for example, Avro does this).
No, it's not bad, and I recommend you always do it on any class you'll reasonably extend over time. For example in our iOS projects we always start with a UIViewController subclass called ViewControllerBase that does nothing but extend Apple's base class (the same can be said for Activity on Android).
When we need to add something in later that should apply to every view controller (analytics perhaps), it's easy to do.
Fortunately, even if you have a lot of classes in your code it's easy to inject your custom base class with a simple search and replace across your codebase.
Do be careful though as once you have a class that's in everything, small changes can of course have broad and possibly unexpected effects. Be sure to test thoroughly!
EDIT:
Regarding subclassing everything, I'd say no. You quickly reach a point of diminishing returns on your time and utility. A common view controller base is pretty standard, as for buttons and so on probably not so much. It depends entirely on what you want to do that you think might need custom functionality. If you want to log every user action, then maybe you do want to subclass every control, but in that case it might be better to just log touch events. At the end of the day though, are you really going to parse all the data that gets generated? Probably not. So make sure you have a solid use case before you go crazy subclassing.
In my opinion there are some cases in which it makes sense to derive classes of a Framework.
At work we used derived classes for the UI-Elements to have control over their behavior.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How would one best organise his GUI. I have a JFrame which will hold my application. Currently I have put all JPanel, JTables and others which will fill up the JFRame inside the custom JFrame class.
I instantiate these components there and save them in a local field. Would it be a better practice as to make a seperate class for each JPanel,JTable and use getters and setters to manipulate the objects?
For example. My current GUI class is about 3500 lines long which gets more complicated over time.
Thanks in advance.
EDIT (he wanted screenie):
I would definitely suggest you start to separate your GUI components into different files, it will help in the long run. As far as best practice goes, I think it is better than cluttering a file with multiple classes even if they are related to each other. The only benefit I can see is you have only 1 file to open to see all the GUI code.
As you said, having a long class (3500ish lines) can make it troublesome to maintain. Organize them in proper packages too while at it. Like making a gui package, or whatever name you feel is appropriate, and so on.
Good advices are given in the answers of the questions tagged user-interface and organization
Break up your GUI code into custom panels.
ie:
class MyPanel extends JPanel { .. }
You should be able to break up the frame into logically distinct panels.
For a busy frame maybe I would have three custom panels. But this can drastically vary depending on what you have.
Also have a controller class. The controller handles backend calls to delegates, and event listening. Your GUI classes, eg customer panels, or custom frame should contain barely any if or loop statements. All that kind of logic should be in your controller.
More complex GUI code is usually generated by an IDE and not hand-coded. Sometimes, you might edit the generated code to get certain effects, but for very complex setups it becomes overly burdensome to hand-write the Swing code. Better to use a tool to generate it for you.
If you already have 3,500 lines of code, it's probably time for you to consider a GUI builder to take some of this work away from you. The learning curve can be steep, and it's not the easiest thing to do, but I would suggest it's way easier than hand-modification of a large GUI.
So basically, the answer is that for moderate/complex GUIs, people don't usually do it the way that you're doing it.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've been using Sonar code quality management platform for some time, and for the most cases I find it very helpful in revealing hidden design flaws of my code base.
However, there's one rule that gives me more annoyance than help and that is its check for 'cyclic package reference' violations.
I guess I fully understand where such a dependency between packages is a bad thing. For example, in a typical 3-tier presentation/service/persistence layered design, it's almost always a bad idea to let the database handling code have a reference back to UI related classes. I have no problem with calling it a 'violation'.
But let's consider other cases, i.e. like designing an IDE-like application. Say, we have a main package which contains an Application interface, which defines List<View> Application.getViews() method to reference application's views.
However, when the View interface has an Application getApplication() method to refer back to its parent application, which I believe is a quite common design, it will introduce a cyclic reference, provided each of the interfaces are separated in com.myapp.ui, and com.myapp.ui.view respectively.
Of course, you can just put the View interface into the com.myapp.ui to break the cycle. But when you have various other view related APIs in com.myapp.ui.view, many of them another abstract APIs like AbstractView, ContentView, AbstractContentView, etc. I wonder if it's more advisable to keep them in separate packages for a management purpose.
And consider the said application has many other similar cases like com.myapp.ui.action, com.myapp.ui.perspective, etc. which would really make com.myapp.ui package crowded if we are to put them all in there.
So, what approach do you suggest to handle such a situation? Are really every cyclic package references a bad thing? Or if I have to live with them, how do you configure Sonar to check only real, problematic cycles?
Every absolute -- except this one ;) -- is going to be wrong some of the time. So, is every cyclic reference bad? No. You have to use your judgement.
But if you do introduce a cyclic dependency, it's worth asking if you really need it, and why. The tl;dr is that more often than not, you may find that breaking the cycle can improve your modularity, and in particular your ability to test components separately.
To use your example, does a view really need a getApplication(), which presumably returns a relatively "heavy" object (ie, one that itself needs a database, network, etc etc)? Maybe... but maybe not. If what you really need from that getApplication is something with a few callbacks (such as when a user initiates some action), then it could be useful to create an interface in some common package for that callback. So, rather than:
com.foo.app.Application
com.foo.view.View
Application getApplication()
You'd have:
com.foo.common.Callback // maybe just a Callable, Runnable, etc?
com.foo.app.Application
provides a Callback for some action foo
com.foo.view.View
Callback getFooCallback()
The question you should be asking is: what does that give me? It could be that you have to stub out so much that it doesn't give you much -- though that may suggest you can break apart your classes some. But it could be that it actually makes it easier to test your view, because now your unit test can (1) test the view without spinning up a whole application, and (b) provide a "dummy" callback that does something like saving a string that describes the action, and then your unit test asserts that it saved the right string.
And indeed there is an open JIRA ticket to prevent considering a cycle between father/child packages as a quality flaw : http://jira.codehaus.org/browse/SONAR-3452
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Its a pretty basic question but I am new to Java designing to please excuse me. :)
I want to know in which scenarios we need to separate the class behavior from the class itself.
for e.g.
If I have an class Employee, I will have some data in it like - name, age etc. Also this class will have some behavior like doWork() etc. Now in what scenario we can have data and the behavior inside once class (Employee) only and in which scenario we need to have 2 different classes for Employee data (EmployeeDTO) and behavior (EmployeeService)
Very subjective question but am looking for some inputs on a design of a small application where I am taking data from a text file. Should I put the data and behavior in different classes or same? What will be your reason to justify this decision?
PS: Any links to information on this will also be very useful :)
Thankyou
Good object-oriented design advocates that each class obey the Single Responsibility Principle. Which I can't summarize any more eloquently than the wikipedia entry:
Martin defines a responsibility as a reason to change, and concludes
that a class or module should have one, and only one, reason to
change. As an example, consider a module that compiles and prints a
report. Such a module can be changed for two reasons. First, the
content of the report can change. Second, the format of the report can
change. These two things change for very different causes; one
substantive, and one cosmetic. The single responsibility principle
says that these two aspects of the problem are really two separate
responsibilities, and should therefore be in separate classes or
modules. It would be a bad design to couple two things that change for
different reasons at different times.
If you think about it, you could jam all of your Java code into one class file, but you don't. Why? Because you want to be able to change, maintain, adapt and test it. This principle says that instead of dividing your code up arbitrarily into different modules, you should take the tact that things should be broken up by their logical responsibilities. This generally means more, small modules which we know to be easier to change, maintain, adapt and test.
I personally would recommend that you factor your code out into smaller discrete classes and combine them later if this proves to be unreasonable -- this will become obvious to you. Its much easier to combine loosely-coupled code in the future than it is to factor out tightly-coupled code.
Do the simplest thing possible. You can always make your code more generalized later and there's a good chance you won't even have to do it.
Apply YAGNI principle every time you need to make a decision. Extreme Programming wiki is also a nice reading.
Put everything into one class right now. When you see your Employee is getting too fat then you can do some refactoring - for example, move method to another class. In statically typed languages like Java it is super easy because compiler helps a lot and IDE support is great.
Reading from file, for example, looks like an obvious candidate to extract to a separate loader class. On the other hand if you have a very common format as input such as XML or JSON you could just create static method List<Employee> Employee.loadFromFile(string fileName) and implement reading logic in a couple of lines of code. It's good enough right now: simple, short and works fine.
May The Real Ultimate Programming Power be with you!
By keeping business logics out of pojo, thus making it a pure transfer object, you have the benefit of loose coupling should one day you find yourself in the situation for the need to switch from Spring framework to EJB JavaBeans.
By putting data and business logic together, it becomes a domain object. The simplest form of managed bean usage promoted in JSF2 uses the domain model whereby the "action" is fused together with form data.
If you choose the first model, you can cleanly separate concerns for designing inheritence and polymorphism for your data objects, while not being bothered if the behaviors defined are making sense, and vice versa.
You use a DTO (like the acronym suggests) when you want to move data around using the lightest weight way possible, such as over the wire to a service.
For the record
Its the classic rich domain object vs anemic domain object.
In general, if you have an UI Object or a Library Object (for example the class Date or the class TextButton), and may be some other kind of Objects then may be you can wrap all in a single Class instead of relies in different classes just for commodity to have all the attributes and methods in the same class.
However, for a classic Business Object (BO) is different. Even if you want a rich domain object, excluding some other problems that i don't want to mention at this point, is the fact that the Business Service (BS) Layer acts as a "fat burning diet plan" and it turns every rich BO into a anemic BO.
Rich BO -------> BS ----------> Anemic BO.