2013年9月22日星期日

A question about the Singleton pattern

 This post last edited by the daituzhang on 2013-09-05 07:37:33
I am a java zero basis , relying on google and baidu in solving this question , if there are minor errors hope you beat the god
because the original title is in English , and I may be a bit inaccurate translation :

1) to establish a class called the Organization , it can not be instantiated more than once but can be provided to the global . It contains only one called getMembers a public method, return a collection.
2) create another class called Member , publicly exposes ( public shall include ?) FirstName, lastName and DateJoined bean properties, please use the appropriate data type
3) create a third called OrganizationHelper class that contains a method for the output of all the Members of the Organization class data . Type of output random.

Then I began to tangle , the first small problem I Baidu down should be a single- case model of the problem , collection I felt a bit like a c + + inside the containers, I use the ArrayList. , but in the end how to obtain this ArrayList member the information I wish to know. Then because under single case mode, this class must provide this to the entire system instance object , then how to return a collection while it ? Or that this instance of the object itself is a collection? So I parted two method , and only became a public setting getMember

second small problem I was tangled What is bean property, Baidu to javaBean and html but it seems to be used together , I was not on the bean property over to understand these two words ?

The third question I just put a small print of the code ...... but that method called XXhelper, C + + object-oriented inside the helper function is outside the class , and I am not sure java is not there such a difference, so I only had one put it as the same class as the main

code is as follows , although the results obtained , but I doubt very much missed several key points

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date; 
import java.util.List;

class Organization {
  ArrayList<Member> List = new ArrayList<Member>();   
  void add(Member temp)
  {
  List.add(temp);   
  }
  private static Organization instance=null;
  private Organization(){}
  static Organization getInstance(){
      if(instance==null)
      instance=new Organization();
      return instance;
  }
  public ArrayList<Member> getMembers()
  {
  return List;
  }
  
}

class Member                              
{                                                               
 public String firstName;                                     
 public String lastName;                                      
 public Date DateJoined;                                             
                                         
public void set( String firstName, String lastName, Date DateJoined)           
{                                                                                                                         
    this.firstName = firstName;          
    this.lastName = lastName;            
    this.DateJoined = new Date( DateJoined.getTime() ); 
 }                                                                                                                         
                                                            
 public String getFirstName()
 {
  return this.firstName;
 }
 public String getLastName()
 {
  return this.lastName;
 }
 public Date getDateJoined()                      
 {                                                                                                                         
   return new Date( this.DateJoined.getTime() );
 }                                                                                                                        
}


public class OrganizationHelper{
    public static void main(String args[]){
     Organization test=Organization.getInstance();
     Member member1 = new Member();
     Member member2 = new Member();
     Date date1 = null;
     Date date2 = null;
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd");
try {
            date1 = fmt.parse("1992-06-12");
     date2 = fmt.parse("2001-03-03");
} catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
member1.set("Tom","Cruise",date1);
member2.set("Xiao","Lizi",date2);
        test.add(member1);
        test.add(member2);
        ArrayList<Member> List = test.getMembers();
        for(int i=0;i<List.size();i++)
        {
         System.out.println(List.get(i).firstName);
         System.out.println(List.get(i).lastName);
         System.out.println(List.get(i).DateJoined);
        }
        
    }
}


------ Solution ------------------------------------ --------


1) the meaning of this subject is to instantiate the control , the control is instantiated in Java, there are two common methods :

a. enum type instantiated control comes naturally , and on reflection , deserialization hack like immunization,
b. ordinary classes can be constructed by restricting 【 Methods】 visibility to control instantiation ( may be reflected, like deserialization means hack, hack but here should not be considered ) , such as the constructor is defined as private. (Java , if you do not write constructor , there 's a default public constructor without parameters )

instantiate control, a situation is only allowed to generate a global instance , which is usually said "single case ."

So a ) is probably the following:



import java.util.Collection;
import java.util.Collections;

public class Organization {
  
  private static Organization INSTANCE = new Organization();
  
  public static Organization getInstance() {
    
    return INSTANCE;
  }
  
  private Collection<Member> members;
  
  private Organization() {
    
    // TODO ...
  }
  
  public Collection<Member> getMembers() {
    
    return Collections.unmodifiableCollection(members);
  }
}


user code to get Member is probably this :


    for(Member member : Organization.getInstance().getMembers()) {
      
      // TODO ...
    }

------ Solution ------------------------------------- -------
I am not a god . . . I talk about my views
first question
mode getInstance method was simple interest plus the public, in order to provide a global , is to use the class name directly.
The second question
bean should be here refers to the entity class Member bars. . .
Member li coupled with arg constructor and constructor with no arguments , set and get methods
DateJoined direct assignment on the line
third title
OrganizationHelper belongs tools , plus a static method of printing on the line.
I tried to write a specific follows:
import java.util.ArrayList;
import java.util.Date;

public class Organization {
  private ArrayList<Member> List = new ArrayList<Member>();   
  public void addMember(Member temp)
  {
  List.add(temp);   
  }
  private static Organization instance=null;
  private Organization(){}
  public static Organization getInstance(){
      if(instance==null)
      instance=new Organization();
      return instance;
  }
  public ArrayList<Member> getMembers()
  {
  return List;
  }
}

class Member                              
{                                                               
 public String firstName;                                     
 public String lastName;                                      
 public Date dateJoined; 
 
 public Member() {
 
 }
                                         
public Member( String firstName, String lastName, Date dateJoined)           
{                                                                                                                         
    this.firstName = firstName;          
    this.lastName = lastName;            
    this.dateJoined = dateJoined; 
 }

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public Date getDateJoined() {
return dateJoined;
}

public void setDateJoined(Date dateJoined) {
this.dateJoined = dateJoined;
}                                                                                                                         
                                                            
}



public class OrganizationHelper{

public static void showInfo(Organization organization) {//打印方法
List<Member> members = organization.getMembers();
for(int i=0; i<members.size(); i++) {
System.out.println(members.get(i).firstName);
         System.out.println(members.get(i).lastName);
         System.out.println(members.get(i).dateJoined);
}
}

    public static void main(String args[]){//入口函数放哪里都可以
     Organization test=Organization.getInstance();
     Date date1 = null;
     Date date2 = null;
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd");
try {
            date1 = fmt.parse("1992-06-12");
     date2 = fmt.parse("2001-03-03");
} catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
Member member1 = new Member("Tom","Cruise",date1);
     Member member2 = new Member("Xiao","Lizi",date2);
        test.addMember(member1);
        test.addMember(member2);
        OrganizationHelper.showInfo(test);
    }
}



------ Solution ------------------------------------ --------


2) bean, called java bean, POJO, entity , etc. These nouns , usually refers to the most simple classes : There are members, each with getter ; and setter methods , and these getter and setter methods are named according to the rules : X members getter method is public X getX ();

This naming convention is for reflection and friendly , when you know that this class has a Field is String firstName, you will know that this class must have methods : public void setFirstName (String) to give firstName assignment .

reflection -friendly , so other code ( usually the framework of implementation of the code ) will be able to use reflective ways this kind of object to serialize and deserialize objects stored in a manner commonly used is XML, so you " Baidu to javaBean but it seems to be used and html together "

example reads Member categories:



import java.util.Date;

public // <-- publicly exposes
class Member {
  
  private String firstName;
  
  private String lastName;
  
  private Date joinedDate;

  public String getFirstName() {
    
    return firstName;
  }

  public void setFirstName(String firstName) {
    
    this.firstName = firstName;
  }

  public String getLastName() {
    
    return lastName;
  }

  public void setLastName(String lastName) {
    
    this.lastName = lastName;
  }

  public Date getJoinedDate() {
    
    return joinedDate == null ? null : new Date(joinedDate.getTime());
  }

  public void setJoinedDate(Date joinedDate) {
    
    this.joinedDate = joinedDate == null ? null : new Date(joinedDate.getTime());
  }
}


stored in XML format can be:


/*
 * <Member>
 *   <FirstName>Raistlin</FirstName>
 *   <LastName>Majere</LastName>
 *   <JoinedDate>2013-09-05</JoinedDate>
 * </Member>
 */

------ Solution ------------------------------------- -------


3) 2 ) The entity class to store information purposes only , so only the getter and setter methods , where the helper class is called " business logic ", and the business logic and entity classes are treated separately for clearer dimensions, and the entity class reuse.

example has the following memberlist.xml:


<?xml version="1.0" encoding="UTF-8"?>
<root>
  
    <Member>
      <FirstName>123</FirstName>
      <LastName>A</LastName>
      <JoinedDate>2013-09-05</JoinedDate>
    </Member>
    
    <Member>
      <FirstName>124</FirstName>
      <LastName>B</LastName>
      <JoinedDate>2013-09-05</JoinedDate>
    </Member>
    
    <Member>
      <FirstName>125</FirstName>
      <LastName>C</LastName>
      <JoinedDate>2013-09-05</JoinedDate>
    </Member>
    
    <Member>
      <FirstName>126</FirstName>
      <LastName>D</LastName>
      <JoinedDate>2013-09-05</JoinedDate>
    </Member>
    
    <Member>
      <FirstName>127</FirstName>
      <LastName>E</LastName>
      <JoinedDate>2013-09-05</JoinedDate>
    </Member>
</root>


simple finish Organization categories are as follows:



import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Organization {
  
  private static final Organization INSTANCE = new Organization();
  
  public static Organization getInstance() {
    
    return INSTANCE;
  }
  
  private Collection<Member> members;
  
  private Organization() {
    
    members = loadMembers();
  }
  
  private Collection<Member> loadMembers() {
    
    try {
      
      List<Member> result = new ArrayList<Member>();
      Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
              getClass().getResourceAsStream("memberlist.xml"));
      
      DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
      
      NodeList list = doc.getDocumentElement().getChildNodes();
      Map<String, Field> fields = fieldsOf(Member.class);
      
      for(int k=0; k<list.getLength(); k++) {
        
        Node node = list.item(k);
        if( !node.getNodeName().equals("Member") )
          continue;
        
        Member member = Member.class.newInstance();
        
        NodeList l = node.getChildNodes();
        for(int j=0, len=l.getLength(); j<len; j++) {
          
          Node m = l.item(j);
          String name = m.getNodeName();
          Field field = fields.get(name);
          if( field == null )
            continue;
          
          String methodName = "set" + name;
          if( field.getType().equals(Date.class) ) {
            
            Method method = Member.class.getMethod(
                    methodName, new Class<?>[]{Date.class});
            Date value = format.parse(m.getTextContent());
            method.setAccessible(true);
            method.invoke(member, value);
          }
          else {
            
            Method method = Member.class.getMethod(
                    methodName, new Class<?>[]{String.class});
            method.setAccessible(true);
            method.invoke(member, m.getTextContent());
          }
        }
        
        result.add(member);
      }
      return result;
    }
    catch (Exception e) {
      
      e.printStackTrace();
      throw new RuntimeException(e);
    }
  }
  
  private Map<String, Field> fieldsOf(Class<?> type) {
    
    Map<String, Field> result = new HashMap<String, Field>();
    Field[] fields = type.getDeclaredFields();
    for(Field f : fields)
      result.put(Character.toUpperCase(f.getName().charAt(0)) + f.getName().substring(1), f);
    return result;
  }
  
  public Collection<Member> getMembers() {
    
    return Collections.unmodifiableCollection(members);
  }
}


So OrganizationHelper class something like this :



import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class OrganizationHelper {
  
  public void print(Member member) {
    
    if( member == null )
      throw new NullPointerException();
    
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    System.out.printf("%-15s%s%n", "First Name:", member.getFirstName());
    System.out.printf("%-15s%s%n", "Last Name:", member.getLastName());
    System.out.printf("%-15s%s%n", "Joined Date:", format.format(member.getJoinedDate()));
    System.out.println();
  }
  
  public static void main(String[] args) {
    
    OrganizationHelper helper = new OrganizationHelper();
    
    for(Member m : Organization.getInstance().getMembers())
      helper.print(m);
  }
}



------ Solution ------------------------------------ --------


Yes, see the 7th floor sample code.

practical applications generally do not call their own XML parsing library (DOM, JAX ......), because Java has built JAXB, through to the class with appropriate annotation, it JAXB can be used to automatically load the object or objects written in xml. Another framework like Spring can help you accomplish .
------ Solution ---------------------------------------- ----


1 - yes, so here you need to write private Organization () {...}

2 - Yes , getInstance is a static method calls are returned each unique instance that

3 - See the 7th floor

4 - Collection is more abstract Interface " collection " , for example, can be tree set, can be a hash map, can also be a list or array , which is defined by all the " collection" behavior should have
Collections.unmodifiableCollection acts as defensive copy, add a layer of "shell " into a read-only , just do not want external code freely change the internal state of the Organization

5 - yes, see the 7th floor

------ Solution ------------------------------------ --------


DateJoined bean properties that do not know what the other I would literally do the following :


import java.util.ArrayList;
import java.util.Collection;

public class Organization
{
private static Collection<Member> collection = new ArrayList<Member>();

private Organization()
{
}

//因为就是这么一个实例所以静态方法了,方便以后使用
public static Collection<Member> getMembers()
{
return collection;
}
}



public class Member
{
private String FirstName;
private String lastName;

public Member(String firstName, String lastName)
{
this.FirstName = firstName;
this.lastName = lastName;
}

public String getFirstName()
{
return FirstName;
}

public void setFirstName(String firstName)
{
FirstName = firstName;
}

public String getLastName()
{
return lastName;
}

public void setLastName(String lastName)
{
this.lastName = lastName;
}

}



import java.util.ArrayList;

public class OrganizationHelper
{
public void outOrganizationMember()
{
// 强转类型
// Organization.getMembers()取得的是Collection<Member>
// Collection<Member>的实际类型是ArrayList<Member>
ArrayList<Member> members = (ArrayList<Member>) (Organization.getMembers());

for (Member member : members)
{
System.out.println(member.getFirstName() + "\t" + member.getLastName());
}
}
}


The only depressing is the first topic that " it contains only one called getMembers the public method", only a public way, that it is the reflection data written into Tim ? Or every time when it put a plus data type , or is there now no way to learn . . .


------ For reference only ---------------------------------------
1. I want to ask click "Java in the constructor if you do not write , there 's a default public constructor with no arguments " is not if you do not mention it public or private, are unified by default into public?
2. So the question really is commonly referred to as single cases do ?
here is not to use getInstance to get the object ?
3. private Organization () {

/ / TODO ...
}
for add member which is not operating or should I say , add member Organization which are not completed , then where is it done ?
4. Collection and Array here is similar to the array , Collections.unmodifiableCollection (members) is the entire array do ?
5. for (Member member: Organization.getInstance (). getMembers ()) {

/ / TODO ...
} whether the output should be the title ?

Thank you so much !
------ For reference only -------------------------------------- -


For me you are the god .
1. then for the original title is , "It should expose a single public method called getMembers" is actually no solution , because the singleton pattern itself already requires a public static getInstance method
2. a reference structure is set, no-argument structures that get you?
public static void main (String args []) entry function is not on the inside which class are possible , even if the class is not public can ?

Sorry I question a lot , trying to learn the ^ _ ^
------ For reference only --------------------- ------------------


I actually got the java reflection around the halo ... I can not be understood as a reflection -friendly java is convenient to be able to have a dynamic assignment and specifies which method, method that is called what name , have a clear specification ?
------ For reference only -------------------------------------- -


very, very grateful to the interpretation of the great God ! This question is learned through half a day than I have read many things !
------ For reference only -------------------------------------- -

Results posted
Though you , but I just finished learning correction lower front back bean write their own not comprehensive , as amended, as follows:


package com.nyohh.bean;

import java.util.Date;

/**
 * 建立另一个叫做Member的类,publicly exposes(公共得包括?) FirstName, lastName 和 Date Joined bean properties,请使用合适的数据类型<br>
 * bean要求:1、public类; 2、不带参数构造方法; 3、通过getXXX、setXXX进行取得、设置属性;
 */
public class Member
{
private String firstName;

private String lastName;

private Date Date; // 我理解为 生日

public Member()
{
}

public String getFirstName()
{
return firstName;
}

public void setFirstName(String firstName)
{
this.firstName = firstName;
}

public String getLastName()
{
return lastName;
}

public void setLastName(String lastName)
{
this.lastName = lastName;
}

public Date getDate()
{
return Date;
}

public void setDate(Date date)
{
Date = date;
}

}




import java.util.ArrayList;
import java.util.Collection;

import com.nyohh.bean.Member;

/**
 * 建立一个叫做Organization的类,它不能被实例化超过一次但是可以提供给全局。它包含仅一个叫做getMembers 的public method,返回一个collection.
 */
public class Organization
{
private static ArrayList<Member> organization = new ArrayList<Member>();

private Organization()
{
}

public static Collection<Member> getMembers()
{

return organization;
}
}




import java.util.Collection;

import com.nyohh.bean.Member;

/**
 * 建立第三个叫做OrganizationHelper的类,包含一个method用于输出Organization类中所有Members的数据。输出的类型随意。
 */
public class OrganizationHelper
{
public static String outOrganizationMembers()
{
String result = null;

Collection<Member> organization = Organization.getMembers();

for (Member member : organization)
{
result += member.getFirstName() + " , " + member.getLastName() + " , " + member.getDate() + " ; \r\n";
}

return result;
}
}


没有评论:

发表评论