I am trying to understand the theory of what a factory pattern is, am I implementing it correctly here? if not what is wrong if correct what should I change?
Interface
public interface Person {
public void setName(String name);
public String getName();
public void setAge(String age);
public String getAge();
public void setGender(String gender);
public String getGender();
}
Male Object
public class Male implements Person
{
public String name;
public String age;
public String gender;
#Override
public void setName(String name) {
this.name = name;
}
#Override
public String getName() {
return null;
}
#Override
public void setAge(String age) {
this.age = age;
}
#Override
public String getAge() {
return null;
}
#Override
public void setGender(String gender) {
this.gender = gender;
}
#Override
public String getGender() {
return null;
}
}
Female Object
public class Male implements Person
{
public String name;
public String age;
public String gender;
#Override
public void setName(String name) {
this.name = name;
}
#Override
public String getName() {
return null;
}
#Override
public void setAge(String age) {
this.age = age;
}
#Override
public String getAge() {
return null;
}
#Override
public void setGender(String gender) {
this.gender = gender;
}
#Override
public String getGender() {
return null;
}
}
Object Factory
public class PersonFactory {
public Person getPerson(String type) {
if(type == "MALE") {
return new Male();
}
else {
return new Female();
}
}
public Person getMale() {
return new Male();
}
public Person getFemale() {
return new Female();
}
}
Main Method
public class main {
public static void main(String[] args) {
PersonFactory pf = new PersonFactory();
Person adam = pf.getPerson("MALE");
}
}
Apart from the String comparison in PersonFactory and with proper implementation of getters in your factory members, seems a descent implementation.
And in your getPerson() logic can be modified as
if (type == "MALE") {
return getMale();
} else {
return getFemale();
}
Looks pretty good, but I'd go ahead and use the factory methods for your "String" method. In other words:
public Person getPerson(String type) {
if(type == "MALE") {
return getMale()
}
else {
return getFemale();
}
}
That way you only have to update the methods if you want to change things in one place, for example if you decide to do something special in the getFemale() or getMale()s.
You should use "MALE".equals(type) instead of type == "MALE". Otherwise your are doing good with factory pattern.
I would implement another approach. The first thing, I would make gender as an enum:
public enum Gender {
Male, Female
}
Note, that Male and Female classes share the same data and semantics to work with this data. I mean name, age and gender.
So, I would implement an abstract class that handles this data. Please note, that class fields should be private, not public.
public abstract class AbstractPerson implements Person {
private String name;
private String age; // maybe int ?
private Gender gender;
public AbstractPerson() {
}
#override
public void setName(String name) {
this.name = name;
}
#override
public String getName() {
return name;
}
#override
public void setAge(String age) {
this.age = age;
}
#override
public String getAge() {
return age;
}
#override
public Gender getGender() {
return this.gender;
}
#override
public void setGender(Gender gender) {
this.gender = gender;
}
}
And it is better to hide this implementation. So we hide it into the factory class:
public class PersonFactory {
private static PersonFactory instance = new PersonFactory();
public static PersonFactory getInstance() {
return instance;
}
public Person getPerson(Gender gender) {
return new AbstractPerson(gender);
}
public Person getMale() {
return getPerson(Gender.Male);
}
public Person getFemale() {
return getPerson(Gender.Female);
}
private PersonFactory {
}
private static class AbstractPerson implements Person {
private String name;
private String age; // maybe int ??
private Gender gender;
public AbstractPerson(Gender gender) {
this.gender = gender;
}
#override
public void setName(String name) {
this.name = name;
}
#override
public String getName() {
return name;
}
#override
public void setAge(String age) {
this.age = age;
}
#override
public String getAge() {
return age;
}
#override
public void setGender(Gender gender) {
this.gender = gender;
}
#override
public Gender getGender() {
return this.gender;
}
}
}
And, use case for this factory:
PersonFactory factory = PersonFactory.getInstance();
Person malePerson = factory.getMale();
Person femalePerson = factory.getFemale();
UPDATE: 15 Sept, 2015
Please note, if you have many kinds of objects, to be produced by factory, then it is advised to have a general method like getPerson(Gender gender) I've just added above in the code.
Related
my class.java content
package pkg1;
import pkg2.*;
public class myclass {
public static void main(String[] args) {
// TODO Auto-generated method stub
student stu = new student();
stu.getName("go");
}
}
contentof student.java
package pkg2;
public class student {
public int id;
String name;
int rollno;
int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRollno() {
return rollno;
}
public void setRollno(int rollno) {
this.rollno = rollno;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I want to initialize variable of student.java of pkg 2 from myclass.java
but its showing field is not visible i have imported contents of pkg2 in pkg1 myclass.java and also have declared the member function of student.java as public
How did you know it is not accessible? Did you encounter any error statement saying this? Take this as a rule of thumb to read the errors accurately before jumping to conclusions.
Try putting this in you main function.
student stu = new student();
stu.setName("go");
System.out.println(stu.getname());
Set the name using the setter first. Only then will you be able to get the name via the getter.
BTW you need to learn a lot of coding Java conventions as well. Like classnames should be starting with a capital. student -> Student.
I'm not completely sure what you're asking here, but first as pointed out by several of the comments to your question you cannot pass any arguments to getName() as it doesn't take any arguments. Secondly, as also pointed out in the comments, please conform to the Java naming convention.
package pkg1;
import pkg2.*;
public class MyClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
Student stu = new Student();
stu.setName("go");
//Verify the name's been set
System.out.println(stu.getName());
}
}
package pkg2;
public class Student {
private int id;
private String name;
private int rollno;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRollno() {
return rollno;
}
public void setRollno(int rollno) {
this.rollno = rollno;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
I am trying to integrate gson in my Play! 2.x. I am using gson & jongo and facing this error : http://hastebin.com/agewopocen.bash
Here is my model class:
public class Person extends MongoModel<Person>
{
ObjectId _id;
String name;
int age;
public Person()
{
super(Person.class, "person");
}
public Person(String name, int age)
{
super(Person.class, "person");
this.name = name;
this.age = age;
System.out.println();
}
#Override
public Person setModel()
{
return this;
}
#Override
public ObjectId getId()
{
return null;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String toJson()
{
return new GsonBuilder().create().toJson(this);
}
#Override
public String toString()
{
return new Gson().toJson(this);
}
}
I don't know what a "TypeAdapter" is (mentioned in the error log in the above link) and I am sure that we can get this working without using it. But, I dont know what I am missing.
Here is the code I tried (without Play, in regular Java) and it works.
public class Test
{
public static void main(String[] args)
{
Person nfe = new Person(10, "nfe");
String s = new Gson().toJson(nfe);
System.out.println(s);
}
public static class Person {
int age;
String name;
public Person(int age, String name)
{
this.age = age;
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
}
}
Output :
{"age":10,"name":"nfe"}
Can someone help me in fixing this?
Well so I'm trying to parse a bit of JSon. I succeeded to parse:
Member.json:
{"member":{"id":585897,"name":"PhPeter","profileIconId":691,"age":99,"email":"peter#adress.com "}}
but what if I need to parse:
{"Members":[{"id":585897,"name":"PhPeter","profileIconId":691,"age":99,"email":"peter#adress.com"},{"id":645231,"name":"Bill","profileIconId":123,"age":56,"email":"bill#adress.com"}]}
Ofcourse I searched the web, I think, I need to use "List<>" here private List<memberProfile> member;but how do I "get" this from my main class??
I used this to parse the first string:
memeberClass.java
public class memberClass {
private memberProfile member;
public memberProfile getMember() {
return member;
}
public class memberProfile{
int id;
String name;
int profileIconId;
int age;
String email;
//Getter
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getProfileIconId() {
return profileIconId;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
}
}
memberToJava.java
public class memberToJava {
public static void main(String[] args) {
Gson gson = new Gson();
try {
BufferedReader br = new BufferedReader(new FileReader("...Member.json"));
//convert the json string back to object
memberClass memberObj = gson.fromJson(br, memberClass.class);
System.out.println("Id: " + memberObj.getMember().getId());
System.out.println("Namw: " + memberObj.getMember().getName());
System.out.println("ProfileIconId: " + memberObj.getMember().getProfileIconId());
System.out.println("Age: " + memberObj.getMember().getAge());
System.out.println("Email: " + memberObj.getMember().getEmail());
} catch (IOException e) {
e.printStackTrace();
}
}
}
see below code
MemberClass.java
import java.util.List;
public class MemberClass {
private List<MemberProfile> member;
public List<MemberProfile> getMember() {
return member;
}
public void setMember(List<MemberProfile> member) {
this.member = member;
}
public class MemberProfile {
int id;
String name;
int profileIconId;
int age;
String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getProfileIconId() {
return profileIconId;
}
public void setProfileIconId(int profileIconId) {
this.profileIconId = profileIconId;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
}
Main Class
import com.google.gson.Gson;
public class MemTest {
public static void main(String[] args) {
String json = "{'member':[{'id':585897,'name':'PhPeter','profileIconId':691,'age':99,'email':'peter#adress.com'},{'id':645231,'name':'Bill','profileIconId':123,'age':56,'email':'bill#adress.com'}]}";
MemberClass memberClass = new Gson().fromJson(json, MemberClass.class);
System.out.println(new Gson().toJson(memberClass));
}
}
Output
{"member":[{"id":585897,"name":"PhPeter","profileIconId":691,"age":99,"email":"\u0027peter#adress.com\u0027"},{"id":645231,"name":"Bill","profileIconId":123,"age":56}]}
Hi I made some changes to your application and it seems to work now ! You where quite close alls you need is a wrapper for the array.
public class memberWrapper {
private List<memberClass> Members;
public List<memberClass> getMembers() {
return Members;
}
public void setMembers(List<memberClass> members) {
this.Members = members;
}
}
Then I changed youir original class a little:
public class memberClass {
int id;
String name;
int profileIconId;
int age;
String email;
//Getter
public int getId() {
return id;
}
public String getName() {
return name;
}
public int getProfileIconId() {
return profileIconId;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
}
and then in the main:
BufferedReader br = new BufferedReader(new FileReader("stuff.json"));
//convert the json string back to object
memberWrapper memberObj = gson.fromJson(br, memberWrapper.class);
System.out.println("Id: " + memberObj.getMembers().get(0).getId());
It should work now the important thing when dealing with JSOn is to just make sure the key matches the name of your variables.
I have a method which creates a new object Student and adds it to an array list studentRegister:
public void addStudent(String name, String age)
{
studentRegister.add(new Student(name, age));
}
it calls the Student class constructor here:
public Student(String name, String age)
{
this.name = name;
this.age = age;
}
This works but it is bad for maintainability as i have to change any additional parameters in both the Student class and the addStudent method. How do I input the parameters at the addStudent stage without having them harcoded in the addStudent method?
just do this:
public void addStudent(Student s)
{
studentRegister.add(s);
}
And in constructer/ other methods you can call the above method as below:
public Student(String name, String age)
{
this.name = name;
this.age = age;
addStudent(this); //here is the call to the above method
}
You should pass a student object - Instead of the two values.
public void addStudent(Student student)
{
studentRegister.add(student);
}
Using
public void addStudent(final Student student) {
studentRegister.add(student);
}
is the better aproach.
Maybe you're looking for a simpler way to build the object. e.g. using chain setters:
public class Student {
private String name;
private String age;
private String address;
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public String getAge() {
return age;
}
public Student setAge(String age) {
this.age = age;
return this;
}
public String getAddress() {
return address;
}
public Student setAddress(String address) {
this.address = address;
return this;
}
}
So, would then:
Student student = new Student().setName("User")
.setAge("30")
.setAddress("New York");
Another way for build the object with normal setters:
Student student = new Student(){{
setName("User");
setAge("30");
setAddress("30");
}};
In the java, commons beanutils, try to set property 'address' and 'creditCardList' to object, but it gave me error :
java.lang.NoSuchMethodException: Property 'address' has no setter method in class 'class com.dao.Student'
but I have this method there. The code is here:
public class Main {
public static void main(String[] args) {
Object student = new Student("John");
Object address = new Address("NJ");
try {
PropertyUtils.setProperty(student, "address", address);
//----------
List list = new ArrayList();
Object creditCard = new CreditCard();
list.add(creditCard);
PropertyUtils.setProperty(student, "creditCardList", list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student {
private String name;
private Address address;
private List<CreditCard> creditCardList;
public Student(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<CreditCard> getCreditCardList() {
return creditCardList;
}
public void setCreditCardList(List<CreditCard> creditCardList) {
this.creditCardList = creditCardList;
}
}
class Address {
private String name;
public Address(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class CreditCard{
private String cardName;
public String getCardName() {
return cardName;
}
public void setCardName(String cardName) {
this.cardName = cardName;
}
}
Your class Student should be a public class , try making it public and rerun your code.
I moved Student to a own file and made it public, that worked fine :)