OOP Design, Calling Certain Methods Outside of a Main Class - java

In my class, we are to create a project with several Main classes and shared classes. In one specific main class, called UserApp, I create an object of the class UserInterface, which deals directly with a file, called Log.txt.
I create an object of the class,DataStorage inside of UserApp, which I use to call a method that returns a String value back to UserApp. I then take that string value and pass it to a method in UserInterface which will write to the file Log.txt. For Example:
public class UserApp {
public static void main(String[] args) {
UserInterface ui = new UserInterface();
String[] commands = ui.readCommandLine();
while(!ui.isFileEnd()){
switch(command[0]){
case "LI": ui.displayThis(dataStorage.listById());
break;
case "QI": ui.displayThis(dataStorage.queryById(command[0]));
}
}
}
}
public class DataStorage {
public String queryById(String id) {
// Stuff the method does goes here
return stringToReturn;
}
}
To me, this seems like the most OOP way of doing things. I emailed her and asked her if this was the correct use. She said to call ui.displayThis inside of the listById() in DataStorage... that would mean that I need to either create a UserInterface object inside the DataStorage class, or pass the DataStorage object in as a parameter to listById(). If I did it like she said, the method listById() wouldn't return a string, but would be void. For Example:
public class UserApp {
public static void main(String[] args) {
String[] commands = ui.readCommandLine();
while(!ui.isFileEnd()){
switch(command[0]){
case "LI": dataStorage.listById(); // Here is the difference
break;
case "QI": dataStorage.queryById(command[0]); // And here
}
}
}
}
public class DataStorage {
public void queryById(String id) {
UserInterface ui = new UserInterface();
// Stuff the method does goes here
ui.displayThis(stringToDisplay);
}
}
There are more switch statements and methods but I felt they were unnecessary to show for this question. I've done some research on this, and from what I've gathered, I'm not sure that this is a style preference or if one way is better than the other. the way she wants me to do it just doesn't feel right with an OOP language. Which method would actually be correct for OOP design?
Edit: The second part would actually be passing in a UserInterface object as a parameter. This seems to make more sense then creating the object each time. Would this be a better way to do it?

The first thing you should know is that both ways of doing it would "work", meaning that you'd accomplish what you set out to do, which is to retrieve something from data storage and display it in the UI.
However, getting something to just "work" isn't always best. In real world applications, engineers such as myself are concerned with maintainability. Simply put, maintainability means that at some point in the future, I may have to come back in to this piece of code and add functionality, or change the way something works (vs. something like a school project where you write the code, submit it, and then never see it or use it again). If I've got a well-written component that has dependencies on other components only where they're necessary, then I can modify and test the said component easily and be confident that I'm not changing the behavior of other components.
So back to your question - the first method that you proposed has a DataStorage class with one method, queryById, that takes a parameter and returns a value. It doesn't have any dependencies on a display component. This is the correct method of structuring your code in my opinion. The fewer dependencies, the better -- it's easier to maintain, and it's easier to write tests for. If you don't believe me, try to write a unit test using JUnit or another testing framework for both ways of implementing the queryById method -- you'll find that your method is simpler to test because you don't have to mock out or inject or create an instance of the UI component.

With the information you've given, it seems that the first way is designed to be more flexible. Rarely do professionals write systems where the storage layer talks directly to the UI layer.
Your first example seems to follow the MVC pattern. The second example seems to be more like the GoF Command pattern.
Either will work, it's just a question of maintainability.
However, OO design is all about separating concerns of the overall program into smaller cohesive units.

What I don't like about your teacher's solution
Querying something from a data store and writing to a file (which is apparently the applications user interface) are two separate things, and your queryById method shouldn't do both. The fact that you create a UserInterface object in that method makes it even worse, but that could be solved by passing it in the constructor and storing it in a (final) field.
The reason your teacher is suggesting this, is probably because she favors the Tell, Don't Ask principle. See Martin Fowler's Bliki for a good explanation of this principle: http://martinfowler.com/bliki/TellDontAsk.html He also explains why he doesn't use it. As you correctly observed: your queryById method wouldn't return a value. Actually then by definition it wouldn't be a query method anymore, but query methods aren't always bad.
What I suggest
Your DataStore class represents the model, your UserInterface class represents the view. Start from your first solution, add another class to represent the controller, which calls the DataStore and UserInterface, both of which are passed in the constructor by your main method, which is otherwise empty. Due to the fact that the logic is now in the controller instead of the main method, it is testable (probably needing Test Doubles for both the DataStore and the UserInterface).

If it were me, I'd be fine with having listById be a void function that does the displaying (instead of returning a String) ... but I'd do it something like this:
public interface DisplayMethod {
public void display (String s);
}
public class DataStorage {
public void queryById(String id, DisplayMethod displayer) {
// UserInterface ui = new UserInterface(); DELETE THIS LINE
// Stuff the method does goes here
displayer.display(stringToDisplay);
}
}
and in UserApp:
final UserInterface ui = new UserInterface();
...
DisplayMethod displayer = new DisplayMethod () {
public void display (String s)
{ ui.displayThis (s); }
};
...
case "QI": dataStorage.queryById(command[0], displayer);
Or something similar. (You'd have to add final to the declaration of ui.) The effect here is that you can still make queryById be a void function (which is useful if it's going to display more than one string), but you don't hard-wire the information about how to do the displaying into DataStorage, since it really doesn't belong there. Your instinct that the stuff to deal with the UserInterface should be in one place, rather than spread out over several classes, is a very good one. Congratulations. (P.S. I'm not claiming that DisplayMethod is a good name. Naming things is one of my weak points.)

Related

How to efficiently share functions between classes without violating the Liskov Substitution Principle

I have a codebase that was originally created with a number of different options that allow you to get the code to perform the same process in a slightly different way, like this:
public class MainFunction {
public void main(String option){
if (option.equals("vanilla mode")){
this.firstFunction();
}else{
this.differentVersionOfFirstFunction();
}
this.secondFunction();
}
public void firstFunction(){
//First functions code
}
public void secondFunction(){
//Second functions code
}
public void differentVersionOfFirstFunction(){
// different code from First functions code that produces the same type of end result using a slightly different method
}
}
This has gotten gradually more and more complex as various different options are added and the code becomes increasingly convoluted.
To resolve this I had originally planned to create a Parent object, that could then have children with subtlety different variations on their Parents methods when needed. The problem is that I understand that this would violate the Liskov Substitution Principle and indeed I may have children that should be sharing the same method that may not be present in their parent.
So I am left with having the different methods in the same class object, doing the same job in slightly different ways.
public class MainFunction {
public void main1(){
this.firstFunction();
this.secondFunction();
}
public void main2(){
this.differentVersionOfFirstFunction();
this.secondFunction();
}
public void firstFunction(){
//First functions code
}
public void secondFunction(){
//Second functions code
}
public void differentVersionOfFirstFunction(){
// different code from First functions code that produces the same type of end result using a slightly different method
}
}
I suppose I could create a separate Utility class to hold all my various functions, but I was not sure if there was a more elegant solution?
I don't see how your examples violate the Liskov Substitution Principle. However, what I see is that they probably violate Open/Closed Principle, meaning that every time you need to modify your program, you edit some MainFunction.java file and have a chance of affecting all possible scenarios of running the program. A better solution involves having a lot of decoupled components so that when you need to modify something, you modify only a tiny portion which is unlikely to affect all scenarios the program might encounter. This is what Single Responsibility Principle is about.
As mentioned in another answer, your scenario seems to be good fit to apply the strategy pattern. This might look as following:
Create interface MainFunction with void main() method, without any options.
Create an abstract strategy class such as AbstractMainFunction with a public abstract void main() member, without any options. This class will implement MainFunction interface.
Create separate implementations of the AbstractMainFunction as needed, e.g. VanillaModeMainFunction and DifferentMainFunction. You may find it useful to keep some shared code in the AbstractMainFunction.
Create a strategy-switcher class, e.g. MainFunctionService. It will have a method, public void main(String option) as in your first example, and probably will have a switch statement like that:
MainFunction strategy = defaultFunction;
switch(option) {
case "vanilla":
strategy = vanillaFunction;
break;
case "different":
strategy = differentFunction;
break;
}
strategy.main();
It looks like a lot of things to do but in the end you will see how this really simplifies maintenance and further development.
Maybe you can try using the strategy pattern, injecting in your MainFunction the Strategy object that you need to use each time. Have a look here

Correct design for certain methods

Consider you have a class RunMe. As the name supposes it is ran by another class. Let's asume through RunMe.run().
RunMe has a private variable with Data that it uses to run different Tests, lets call ist data.
Let's say this data is initialized by RunMe.initialize().
After that, in the run() Method, the first Test is ran with the default values set by the initialize function for data. Let's call that test-method testWithDefaultValues.
We now want to fill our data with some custom data. Let's say we do this using fillData.
Then we want to execute another test using our newly filled data. Let's call this test testWithFilledData.
Our run-method at this point would look something like this
public void run() {
initialize();
testWithDefaultValues();
fillData();
testWithFilledData();
}
Can you see how akward this code looks? It looks AND feels wrong. A thing directly coming into my mind: The only reason testWithFilledData() or also testWithDefaultValues()is actually doing what the name supposes is because of the order in which these functions are called in run. This has to be wrong.
So instead i should eliminate initialize and fillData and do what those functions do in the according test-function?
What if you consider the fact that many more test-functions are going to exist, each of them testing with a different set of data, all of which have to be quite manually filled (data.setField("fooField","fooValue);).
Can someone possibly give a general construct or idea in which he would explain how he would solve the given task properly?
Right now i am really struggeling to find a pattern that "feels nice" and correct. What i am doing currently must be wrong.
Edit: Worth mentioning is that the test-function cannot be generic. For every different variations of data different results have to be considered.
Well, what would happen if you attempt to call testWithDefaultValues() without calling initialize() first? You won't actually be testing with the default values, you will be testing with whatever you previously set data to. I think you should move away from modifying the internal test data in the actual test functions, and perhaps rather have a generic test function that has data passed into it.
This makes a lot of sense if testWithDefaultValues() and testWithFilledData() are actually doing the same thing but with different data.
I think something like this makes more sense:
Data testData = getTestData();
test(testData);
Data fillData = getFillData();
test(fillData);
I believe you should fill only one method with all the code needed for the test you are trying to achieve. You are then able to fill the variables or data for your test accordingly and stage different values for your data to run different test starting always from the same method.
With this simple construct, you are able to create multiple tests method and won't get lost in your code.
EDIT
You should always consider a test method like a blackbox testing. If you consider that you have no idea what's the code running inside the method. All you have to care about is the input and output of you test.
If the same method should produce different output based on different input. The code inside your blackbox remains the same.
However, if your method needs to interact differently with the input to generate the output you need, then, you need to consider writing a different test.
My two cents, hope it helps
I suggest using the Template Method design pattern to create a test framework. You'd probably be better off using a mature test framework like JUnit.
public abstract class TestCase {
// This is the template method.
public final boolean execute() {
initTest();
return runTest();
}
// Init hook method.
public abstract void initTest();
// Test logic hook method.
public abstract boolean runTest();
}
public abstract class BaseTest extends TestCase {
public boolean runTest() {
// This is the common execution for different data sets...
}
}
public Test1 extends BaseTest {
public void initTest() {
// Data init for test 1...
}
}
You can extend BaseTest for each test data set you have. To run the tests:
new Test1().execute();
new Test2().execute();
EDIT: You can of course skip BaseTest if you don't have common test logic. Or you can tailor the template method to add more hooks for whatever makes sense for your particular needs. The main point is to capture the common process in the template method, to isolate common code in some hook methods, and to provide unique concrete overrides in other hook methods.

Java: Using Static Methods for repeated code sections

So I'm learning Java (gasp bet you could've never guessed that), and today I'm focused heavily on making sure that I'm using static methods properly.
My big practice program right now is an account manager program, that I tweak and add to as I learn more and more concepts. One component of it is printing out a list of all the accounts added to the system. Because this list gets summoned more than once, I created a static method that can be invoked to generate it, and placed it above my main method in the code.
My question is: should I do this? Is it a good idea/good programming etiquette to create methods like this for repetitive sections of code? And if the answer to both of those is yes, should I make it a static method?
Here's the code for the static method I'm talking about:
/**
* accountList() method displays a list of all accounts currently loaded into the program
*/
public static void accountList(){
System.out.println(" ACCOUNT LIST");
System.out.println("NUMBER INFORMATION");
for(int num = 0; num < accountArray.size(); num++){
System.out.println(" " + (num + 1) + " " + accountArray.get(num).getAccountName()
+ " : " + moneyFormat.format(accountArray.get(num).getValue()) + " "
+ accountArray.get(num).getCurrencyType());
}
listMax = accountArray.size();
}
Then below this would be my main() method, and periodically within my main would be the invocation of this method to generate an account list:
public static void main(String[] args){
accountList(); //example of how I would invoke this method
}
So, do I have this figured out properly? Am I using this correctly? Thanks.
PS. My accountList() method is in the same class as my main() method, which is why there's no class name before it. That's also why I'm asking, because I know one of the main purposes of the term "static" is that it would be easily accessible from another class, so I'm not sure if it needs to be static if it's in this same class.
Is it a good idea/good programming etiquette to create methods like this for repetitive sections of code?
Having many small methods in stead of fewer large methods is a good practice in terms of maintainability and re-usability.
should I make it a static method?
Static methods are used when they do not depend on state of some particular instance of the class. It is in general avoided since subtype polymorphism is not available for static methods (they can't be overridden). Small utility methods are made static (like Math.sqrt or System.currentTimeMillis()).
Note: (Optional)
When you define methods to re-use the code, the most important aspect is the contract that the method is supposed to fulfill. So the methods should communicate with each other using arguments and return values for predictable behavior. Mutating state of class fields (or even worse static fields) is generally considered a bad idea (you have to do it though sometimes).
You could improve your method to something like following.
public static void printAllAccounts(List<Account> accountList) {
// Your code ...
}
This method specifies which accounts to print, and does not depend on state.
It would be even better if you can delegate it to another class and make it a non static behavior. That way if you come up with better way of printing all accounts, you can replace the behavior without touching this method.
Hope this helps.
Good luck.
Don't repeat yourself (DRY) is a widely accepted principle and good practice, and creating methods for code that would otherwise be duplicated is the simplest and most obvious form for this.
(In some languages/contexts people hint at the potential overhead of a method invocation and its impact on performance. In fact, inlining methods is a common optimization that compilers do. But modern compilers (and particularly, the Just-In-Time-Compiler of the Java Virtual Machine) do this automatically when it is appropriate)
Whether helper methods should be static has already been discussed elsewhere.
My rule of thumb here is: Whenever a method can be static, then it should be static.
A more differentiated view: When a method does not modify instance fields (that is, when it does does not operate on a mutable state), but instead only operates on its arguments and returns a result (and is a "function", in that sense), and when it should not be involved in any form of polymorphism (meaning that it should not be overloaded), then it should usually be made static. (One might have to take aspects of unit testing into account here, but that might lead too far now)
Concerning your specific example:
You have a different problem here: The accountArray obviously is a static field, as well as the listMax variable. And static (non-final, mutable) fields are usually a horrible idea. You should definitely review this, and try to make sure that you do not have static fields that describe a state.
If you did this, your method could still be static, and receive the accountArray as a parameter:
public static void accountList(List<Account> accountArray){
System.out.println(" ACCOUNT LIST");
...
}
However, in this form, it would violate another best practice, namely the Separation of Concerns. The method does two things:
it creates a string representation of the accounts
it prints this string to the console
You could then split this into two or three other methods. Depending on the indented usage, these could, for example, be
public static String createAccountInfoString(List<Account> accounts) {...}
public static void printAccountInfo(List<Account> accounts, PrintStream ps) {
ps.println(createAccountInfoString(accounts));
}
public static void printAccountInfo(List<Account> accounts) {
printAccountInfo(accounts, System.out);
}
(note that the method names indicate what the methods do. A method name like accountList doesn't tell you anything!).
However, as others have pointed out: Overusing static methods and passing around the information may be a sign of not properly using object-oriented concepts. You did not precisely describe what you are going to model there. But based on the keywords, you might want to consider encapsulating the account list in a class, like a class AccountList, that, among others, offers a method to print an account list to a PrintStream like System.out.
Here's what a static method is. A static method from the same class, you can just call without the class name, but a static method from another class, you would have to call with the class name. For example, if you have a static method called method1 in a class called Class1, and you're trying to call the method in a different class called Class2, you would have to call the method like this:
Class1.method1();
If you just use method1(), it would show up as an error, and it'll tell you that it can't find the method, because it only searches the class you're in for the method, and it doesn't find it. You would have to put the class name, Class1, so it knows to go search for the method in Class1, and not the class you're in.
As for whether you should use a static method or not, that depends, really, on your preference. Do you know the different between a static method, and a non-static one? I'll just gives you the basics for now. If you have more questions, you can ask.
Okay. A non-static method can only be called when you make an object out of the class the method is in. This is how you make an object:
(CLASS NAME)(OBJECT NAME) = new (CONSTRUCTOR NAME)();
The constructor's name is the same as the class name. And when you call the method, you would put (OBJECT NAME).METHOD NAME(); to call it. As for a static method, I already told you how you can call it. So. Anymore questions?
The use of static methods is something that could remember procedural programming. In fact, if you use static methods you cannot use OOP principles, like polymorphism.
First of all, it is not good that a method, which aims is to print a list, could change program state. Then, in the future, you may want to change the way the list is printed. Let say, you want to print it in file. How would you change your program to satisfy this new requirement if your ar using a static method?
Try to think more OO, and in the beginning, try to put your code inside a dedicated class (i.e. Printer). Then, you can extract an interface from that class, and finally try to apply some design patterns, like Strategy Pattern or Template Method Pattern.
static members of a class (that is variables, method) are not related/associated to the instance/object of the class. They can be accessed without creating object of the class.
General rule of using static method is - "Ask yourself is the property or method of a class should applicable for all of the instance of the class". If the answer is yes then you may use static member.
Consider the following example -
public class Student{
private int noOfStudent;
.......
}
Now you have a Student type. In this case you may consider to make the noOfStudent property static. Since this is not the property of a Student itself. Because all students of a class should share the same property of noOfStudent.
You can find more explanation here
Hope it will Help.
Thanks a lot.

How to unit test a private functionality

I have a question regarding unit testing.
I have a function which does the following thing:
void myFunction(List<MyClass> myList) {
// 1. Sort the list
// 2. Post Process the list
}
Now I want to test this function. But the problem is I should not test these two things at the same time. I am therefore thinking to extract the "Post Process the list" part as a separate function.
But the problem is the task of "Post Process the list" is only used by myFunction and I want to make it private to the class.
If I make it private I won't be able to test it from outside.
What is the general rule of this kind of scenario? Must I change a private function to public only for testing?
Or if there are any other patterns I should use?
Many thanks
The test method only needs to be package-local.
You can call private methods using reflections and there are mocking libraries which allow you to test private methods. But I would just make it package-local as it shows the method is access from elsewhere in the package (which it is either way)
As others have said, you don't need to make the method public, just package visible.
Google Guava has a #VisibleForTesting annotation which is meant for situations like this. You put this annotation on a method, just to document that the reason that the method isn't private is only for testing. The annotation doesn't do anything, it's just meant as a warning for programmers that they shouldn't call it from outside the class. (Some static code checking tool could in principle check if methods with this annotation aren't called from anywhere except inside the class or from test code).
Ofcourse it's kind of ugly to have to modify your code to do this just for testing. If you want to avoid this, you can do tricks with reflection to call the private method:
public class Sandbox {
public static void main(String[] args) throws Exception {
Example e = new Example();
Method m = Example.class.getDeclaredMethod("myFunction", List.class);
m.setAccessible(true);
m.invoke(e, Arrays.asList("one", "two", "three"));
}
}
class Example {
private void myFunction(List<String> data) {
System.out.println("Hey, what are you doing! " + data);
}
}
In general, you should always test the functionality through public methods. If there is some functionality in private methods, which cannot otherwise be tested well enough, that's an indication that the method has a responsibility which should be moved to its own class (this also helps to achieve high cohesion). Then that newly extracted class can be tested directly though its public methods.
Another vote for package-local. Just ensure that your newly exposed method is clearly named and documented so that in future it is not called inappropriately.
It depends.
Dose the sub routine contains common behavior that you should extract ?
Take your first sub routine as example. If you're not sorting your list by Comparator<T>, you should refactor it, then test that Comprartor<T> class instead of your private method. If Post process are actually some algorithm or common business logic, you might want to refactor it using Strategy pattern then test those class you just extract.
The point is, if a private method is complex enough to require a unit-test, then chance is probably you should not put them there, otherwise you should just test through it's public API.
It's a legacy system, and it will take forever to refactor that method.
check Bad Smells in Code : Long method for long method refactor, Method Object is a good strategy for things like this.
It's fine, I just want to test them.
Then you can test through Java reflection API, and I believe there are some mocking framework like PowerMock can also help you.
Below things you may consider for testing a private method.
1.create public method written only for the purpose of testing. (or)
2.create nested class for testing (or)
3.use reflection to test it.
useful link,another useful link from stackoverflow
I typically consider private methods to be part of the method under test. They typically consist of code that has been moved out of the original method to make it leaner and shorter, and more modular. However from a test perspective you would be testing the same code if you moved the content of the private method into your method under test.
The question of trying to isolate the return values of private methods to simulate various conditions is is often valid though. I think its' part of the larger question of how to write testable code.
One approach with very little overhead is to rely on basic overriding of methods. You can make your private methods protected virtual instead, and override them in your test:
Here's an example of that too :
http://www.unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html
The example is C#, but the concept applies to all object oriented languages

Reducing complexity of a method

I have a method that does several tasks. It is part of the business logic of the application, but it is poorly readable because of the many if-then and try-catch blocks and the many log calls.
public class MyClass {
boolean createReport, sendReport, warnIfErrors;
public void archiveAll() {
if (createReport) {
//... ...
}
if (sendReport) {
//... ...
}
if (warnIfErrors) {
//... ...
}
}
The idea is to move the tasks into ad hoc methods and have an "archiveAll" method that may be understood at a glance:
public void archiveAll() {
doCreateReport();
doSendReport();
doWarnIfErrors();
}
But as doing this, two problems arise:
if all methods use a local variable, I'll move it as a class field, but this is not good design
I want to move the test if (createReport) into the method doCreateReport too, because part of the complexity derives from the tests that are done. This makes the sub methods poorly cohesive though.
If you have a lot of local variables that are shared between them it might make sense to make a private class to store them together, perhaps even do something like:
MyReport report = new MyReport(); // or MyReport.doCreateReport(); if it makes more sense
report.send();
report.warnIfErrors();
Again, it really depends on whether the function is currently big enough to warrant something like this.
If you can get away with just passing those common variables as parameters without having huge lists of parameters, do that.
You can also pass the required data as arguments to the methods.
I would do the check before calling a method. If a method is called doCreateReport it should actually do that.
Instead of making variables class fields, just parameterize the function and pass the values around. This has another big advantage that your code will now become more unit-testable. I always promote to have each method to be as independent as possible as it helps in UT.
If you had the name changed to checkAndCreateReport then, will you still think that way:)

Categories

Resources