I came across a refactoring functionality that looks to be useful as I learn eclipse and java. But I'm not sure how this could be useful. Is there a pattern that would benefit from this kind of refactoring? This refactoring option basically extracted out all variables into another class whose name was changed to append Data at the end.
Any examples of WHAT/WHY this kind of refactoring gives us would be really helpful.
Thank you in advance.
Extract Class is mostly used when a class has too many responsibilities; it is trying to do too much. It splits out the class into two individual classes and then transfers some functionality into the other class - obviously there will be a relationship between the classes because you still want all of the code to interact.
You can combine Extract Class with other refactoring patterns such as Move Method and Move Field that will move methods and fields to the other class in such a way that all of the code still works as intended.
This link has a good example of Extract Class: http://sourcemaking.com/refactoring/extract-class
If you had too many fields in your class and you see that this must be a extra class, you can use it.
Example:
public class Person {
private int age;
private String name;
private String street;
private int streetnumber;
}
to:
public class Person {
private int age;
private String name;
private Adress data = new Adress();
}
public class Address {
public String street;
public int streetnumber;
public Address() {}
}
Related
I have a question about OOP implementation and design patterns.
I have a fixed class model which I cannot change (because it is generated automatically each time the application starts). There are many classes there with equals fields like in example below: as you can see the fields city and streets are contained in the both classes.
public class A{
String city;
String street;
String name;
....//get methods
}
public class B{
String city;
String street;
String age;
....//get methods
}
I need to extract an address form the both types of classes and I want to implement it with one method (because it seems to be silly to write the same code twice). If the class model were changeable, I could add a new interface Addressable which A and B could implement.
public interface Addressable{
public String getStreet();
public String getCity();
}
//somewhere in code
public Address getAddress(Addressable addressable){
return new Address(addressable.getCity(), addressable.getStreet());
}
What is the most elegant way to implement the same without interface and without coding the same for different classes?
If you are not able to change A or B, you would have necessarily a degraded solution.
A simple and good designed solution would rely of course on a interface defining an Address retrieval method (Address getAddress()) that A and B would implement.
You could also define a wrapper class :
public class WrapperA implements Addressable {
private final A a;
public WrapperA(A a) {
this.a = a;
}
#Override
public Address getAddress(){
return new Address(a.getCity(), a.getStreet(), etc...);
}
}
But it may be rather clumsy if you have to duplicate this kind code for many classes.
Besides the client will not manipulate any longer a A but a WrapperA class.
It may break the actual client code.
So also here, an interface is required if you want to implement a real adapter.
As said, without redesigning a minimum A or B, a really good solution is complicated.
As workaround, you may define an Address class that provides factory methods to create Address from a A or a B instance.
public class Address{
...
String city;
String street;
...
private Address(){
}
public static Address of(A a){
return new Address(a.getStreet(), a.getCity(), ....);
}
public static Address of(B b){
return new Address(b.getStreet(), b.getCity(), ...);
}
}
Then use these methods to create the Address on the demand as you need it.
You could write adapters to provide a common interface.
public class AdpaterA implements Addressable {
private final A a;
public AdapterA(A a) {
this.a = a;
}
#Override public String getStreet() {
return this.a.street;
}
// other method is omitted as homework ;-)
}
Then you would use the adapter classes for further processing.
I had a similar situation, where classes are generated during the build process. (In my case, the build process would inspect the database, and generate one class per database table, with all the fields.)
You state that the classes are generated when your application starts. In case they are generated during the build process, you can add an extra element to the build process which alters the genreated files. In my case our build servers were only Linux, so I added a sed line to our ant script.
Why saying that Memento is doing its job without violates the encapsulation, while I can implement the simple way but also without violate the encapsulation? What is the use of Memento?
I have a sample program, which will save the student details while user press the save button, and undo the action when user press then undo button.
Sample code below is implementation without using Memento pattern:
Student.java
public class Student
{
private String name;
private String gender;
private int age;
private Contact contact;
public Student(String name, String gender, int age, Contact contact)
{
this.name = name;
this.gender = gender;
this.age = age;
this.contact = contact;
}
//getter and setter
}
Main.java
public class Main extends javax.swing.JFrame implements DocumentListener
{
private Student sCopy, student;
private void btnUndoActionPerformed(java.awt.event.ActionEvent evt)
{
txtName.setText(sCopy.getName());
txtGender.setText(sCopy.getGender());
txtAge.setText(sCopy.getAge() + "");
txtPhone.setText(sCopy.getContact().getPhoneNo());
txtEmail.setText(sCopy.getContact().getEmail());
txtAddress.setText(sCopy.getContact().getAddress());
student = sCopy;
}
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt)
{
sCopy = student;
Contact c = new Contact(txtPhone.getText(), txtEmail.getText(), txtAddress.getText());
student = new Student(txtName.getText(), txtGender.getText(), Integer.parseInt(txtAge.getText()), c);
}
Sample code above works perfectly, but why we need memento while it can be done so easily? I don't see where the implementation above violets the encapsulation...
Summary
Does approach above violates the encapsulation? If not, then what is the purpose of Memento? allow multiple undo? Although implementation above does not allow multiple undo, but that also can be done without applying memento.
In your approach the instance referenced by sCopy exposes all the available setters. If they are used to change values, the undo will not work correctly. This violates encapsulation, since the correctness of the undo depends on the client of your class.
A memento object would not expose any (mutating) methods, and would always be safe to use for exactly restoring the object's state.
Does approach above violates the encapsulation?
Probably. We will see.
First of all, pick some definition of what violates the encapsulation:
Having getters and setters does not in itself break encapsulation.
What does break encapsulation is having a getter and a setter for
every data member (every field, in java lingo). That is one step away
from making all data members public.
Is it your case? You have some getters and setters in the Student, maybe exposing some methods that are not necessary in your application, like gender or name. Even they are necessary, in the future can appear new fields in Student and your solution can't work anymore without violating the encapsulation.
Allow multiple undo?
It's one of the advantages.
Although implementation above does not allow multiple undo, but that also can be done without applying memento.
Yes, but maybe violating the encapsulation.
I know there are a lot of questions around here regarding JAXB and Interfaces and I did some search here but without any luck. So if you think this is already answered go ahead and link it to me please.
Now to my problem:
I have an arraylist filled with objects that get casted to an interface class:
private ArrayList<IEvent> eventLog;
And I want to save the eventLog as XML to file and load it again from the file.
I have a single interface class that gets implemented by a lot of classes.
Because of the amount of implementing classes I have, I want to do something like mentioned here in 3.2.1.
The problem is that I don't seem to get it, cause JAXB tells me every time I try to run the program, that it does not support interfaces.
My Interface looks like this:
public interface IEvent {
public abstract void process();
}
And my implementations look like this:
public class ProjectEdited implements IEvent {
private String newName;
private String newDate;
private int newNeededEmployees;
private int sender;
public ProjectEdited(int sender, String newName, String newDate, int newNeededEmployees) {
this.newName = newName;
this.newDate = newDate;
this.newNeededEmployees = newNeededEmployees;
this.sender = sender;
}
#Override
public void process() {
// call the responsible handler
}
If someone could give me a tip, what kind of annotations I need to use (and where AND WHY!) I would really appreciate it.
I am also open for alternatives for what I want to do, hope someone can help me.
Greetz Saladino
I have been doing Java for 12 years, and I have recently been doing Javascript, and I was wondering if the Java community has considered some kind of flexible constructor mechanism.
Things can get messy with constructors in Java. If there are many different pathways to create an object, then you need a constructor for each.
What if you could have a constructor where you can put in whatever values you like that would match up with a classes internal field :
Person p = new Person([
name:’bob’,
height:123,
address:new Address([
street:’asdf’,
postcode:4232
])
]);
(I am using square brackets here, but you would need some other symbol, as this would conflict with arrays in Java)
Then you define which fields in a class may be used in a constructor combination with an annotation :
public class Person{
#constructable
private String name;
#constructable
private int height;
#constructable
Private Address address;
.....
}
public class Address {
#constructable
private String street;
#constructable
private String postcode;
#constructable
private String city;
.....
}
This would all be syntactic sugar. During compile time, the compiler would work out all the constructors that are needed for a class and update the class accordingly.
Has anything like this ever been proposed a JSR?
Does this break any core philosophy behind Java? (Ie. Constructors should not be so unrestrictive)
This can mostly be achieved by the Builder pattern. This is useful when there is a lot of information required to create the object.
The thing is that I've been coding the following exercise and I wanted to ask you something about it:
Develop a system that meets the following requirements:
Create a test generator reminding the following functional requirements:
There are two types of questions: open and multiple choice. The first ones are textual questions that students must develop to respond. The latter are textual questions that have options for students to choose 1. Each question belongs to a topic and each topic is identified by a code and a description.
An exam has N questions and every question has an answer (entered by the student). It is important to identify the student that takes the test and the examiner (the person who assembled the exam).
In order to generate the test, the examiner must indicate the amount of questions you want for each topic. The questions are selected at random from a database of questions. The correction is made in two parts: automatic correction in multiple choice and manual correction in the open questions.
Generated tests should persist and it must be able to create a copy of each exam for each student. The student completes the test, then get the correction automatically, awaiting for manual correction by the examiner. Finally, to complete the correction, the examiner corrects the open questions.
Reports: List of exams and resolutions showing the questions and answers of each exam for each student along with it's note.
I've already coded my program, but the thing is that I have some doubts about choosing the right classes to build my project, because sometimes I can't tell if all nouns from the requirements should be classes or not, or if it just depends on the scope of the system... Reading a couple of books, I've found that we have to select only nouns that have a meaning, and for that reason we usually omit some of them.
The classes I have are the following:
public class Student {
private String name;
// methods
}
public class Exam { // the examiners create the exams
private int id;
private Examiner examiner;
private List<Question> questions = new ArrayList<Question>();
private List<Test> tests = new ArrayList<Test>();
private Map<Topic, Integer> quantityChosenPerTopic = new HashMap<Topic, Integer>();
private Map<Topic, List<Question>> questionsByTopicDisordered;
// methods
}
public class Examiner {
private String name;
// methods
}
public abstract class Question {
private Topic topic;
private String text;
// methods
}
public class OpenQuestion extends Question {
// methods
}
public class MultipleChoiceQuestion extends Question {
private List<String> options = new ArrayList<String>();
private String correct;
// methods
}
public class Test { // the students take the tests
private int number;
private Student student;
private float mark = -1;
private Map<Question, String> answers = new HashMap<Question, String>();
private Map<Question, Boolean> correction = new HashMap<Question, Boolean>();
// methods
}
public class Topic {
private int code;
private String description;
// methods
}
In the previous version of the system, I also had these classes:
public class Option {
private String option;
// methods
}
public abstract class Answer {
// methods
}
public class OpenAnswer extends Answer {
private String text;
// methods
}
public class MultipleChoiceAnswer extends Answer {
private Option option;
// methods
}
A person who helped me with this decided to take out those last classes: Option, Answer, OpenAnswer and MultipleChoiceAnswer. The reason he gave me was that it has not much sense to have them in the program because they just handle one variable and he recommended me to use them as that. And other person told me that it's important that the code works and it should be understandable by other people, plus it's not recommended to have many little classes that don't have almost nothing or very big classes with lots of code. That's why I wanted to ask you that. Thanks.
I would code it so that the resulting classes will have some behaviour, if a class consists only of information then it's better to view it as a data structure.
So, in my opinion, I would not create classes adding properties first, but their methods, by doing so you automatically exclude data structures from classes.
You said
Reading a couple of books, I've found that we have to select only nouns that have a meaning, and for that reason we usually omit some of them
...in my opinion a meaning reflect actions that could be carried out by a class, methods.