1) 这题目的意思是实例化控制,实例化控制在Java里有两种常用手段: a. enum 类型天生自带实例化控制,并且对反射、反序列化之类的hack免疫, b. 普通类可以通过限制【构造方法】的可见性来控制实例化(可以被反射、反序列化之类的手段hack,不过这里hack应该不在考虑之列),比如把构造方法定义为 private。 (Java中如果你不写构造方法,有一个默认的 public 的无参构造方法)实例化控制中,一种情况是全局只允许产生一个实例,即通常说的“单例”。所以 1) 大概是下面这样: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); } } 用户代码获取 Member 大概是这样的: for(Member member : Organization.getInstance().getMembers()) {
// TODO ... }
我不是大神我说说我的看法 第一题 单利模式getInstance方法得加上public,才能提供给全局,就是用类名直接访问。 第二题 bean这里应该就是指实体类Member吧 Member里加上有参构造方法和无参构造方法,set和get方法 DateJoined直接赋值就行了 第三题 OrganizationHelper属于工具类,加个静态的打印方法就行了。 具体的我试着写了下: 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;
// TODO ... } 里面是不是作add member操作还是说,add member不在Organization里面完成,那么又是在哪里完成的呢? 4. Collection 在这里是不是和 Array 相似的数组,Collections.unmodifiableCollection(members) 是整个数组吗? 5. for(Member member : Organization.getInstance().getMembers()) {
// TODO ... } 中是否应该进行题目中的输出?太谢谢了!
对我来说你就是大神了。 1. 那么对于原题来说,“It should expose a single public method called getMembers”其实是无解的,因为单例模式本身就已经要求有一个 public的getInstance方法 2. 有参结构就是set,无参结构就是get是吗? public static void main(String args[])入口函数是不是放在哪个class里面都是可以的,哪怕class不是public也可以的?不好意思我问题好多,正在努力学习中^_^
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);
1) 这题目的意思是实例化控制,实例化控制在Java里有两种常用手段: a. enum 类型天生自带实例化控制,并且对反射、反序列化之类的hack免疫,
b. 普通类可以通过限制【构造方法】的可见性来控制实例化(可以被反射、反序列化之类的手段hack,不过这里hack应该不在考虑之列),比如把构造方法定义为 private。 (Java中如果你不写构造方法,有一个默认的 public 的无参构造方法)实例化控制中,一种情况是全局只允许产生一个实例,即通常说的“单例”。所以 1) 大概是下面这样: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);
}
}
用户代码获取 Member 大概是这样的:
for(Member member : Organization.getInstance().getMembers()) {
// TODO ...
}
第一题
单利模式getInstance方法得加上public,才能提供给全局,就是用类名直接访问。
第二题
bean这里应该就是指实体类Member吧
Member里加上有参构造方法和无参构造方法,set和get方法
DateJoined直接赋值就行了
第三题
OrganizationHelper属于工具类,加个静态的打印方法就行了。
具体的我试着写了下:
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);
}
}
2) bean,所谓 java bean, POJO, entity 等等这些名词,通常是指最简单的类: 有成员,每个成员有 getter 和 setter 方法,并且这些 getter 和 setter 方法都按规则命名: X 成员的 getter 方法就是 public X getX();这种命名规范是为了对反射友好,当你知道这个类有一个 Field 是 String firstName, 你就知道这个类必然有方法: public void setFirstName(String) 来给 firstName 赋值。对反射友好,所以其他的代码(通常是框架实现的代码)就能用反射的方式对这种类的对象进行序列化与反序列化,常用的存储对象的方式是 XML, 所以你“百度到javaBean但是好像是和html结合起来用的”比如这样写的 Member 类: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());
}
}
存储成 XML 的格式可以这样:
/*
* <Member>
* <FirstName>Raistlin</FirstName>
* <LastName>Majere</LastName>
* <JoinedDate>2013-09-05</JoinedDate>
* </Member>
*/
2. 所以本题的确是通常所说的单例吗?
这里是不是用getInstance来获取对象?
3. private Organization() {
// TODO ...
}
里面是不是作add member操作还是说,add member不在Organization里面完成,那么又是在哪里完成的呢?
4. Collection 在这里是不是和 Array 相似的数组,Collections.unmodifiableCollection(members) 是整个数组吗?
5. for(Member member : Organization.getInstance().getMembers()) {
// TODO ...
} 中是否应该进行题目中的输出?太谢谢了!
对我来说你就是大神了。
1. 那么对于原题来说,“It should expose a single public method called getMembers”其实是无解的,因为单例模式本身就已经要求有一个 public的getInstance方法
2. 有参结构就是set,无参结构就是get是吗?
public static void main(String args[])入口函数是不是放在哪个class里面都是可以的,哪怕class不是public也可以的?不好意思我问题好多,正在努力学习中^_^
我其实被java中的反射绕晕...我是不是可以理解为反射友好就是java为了能够方便动态赋值而规定了要有哪些method,method该叫作什么名字,有一套明确的规范?
3) 在 2) 中的实体类只做存储信息之用,所以只有 getter 和 setter 方法,这里的 helper 类就是所谓“业务逻辑”了,业务逻辑和实体类分开,是为了更清晰的层面,以及实体类的复用。比如有下面的 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>
简单完成 Organization 类如下: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);
}
}
那么 OrganizationHelper 类大概是这样的: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);
}
}
是的,详见7楼示例代码。实际应用中一般不用自己调用 XML parsing 的库(DOM,JAX……),因为 Java 内建了 JAXB,通过给类加适当的 annotation,就可以用 JAXB 自动加载对象或把对象写成xml。 另外像 Spring 这样的框架也可以帮你完成。
1 - 是的,所以这里你需要写 private Organization() { ... }2 - 是的, getInstance 是静态方法,每次调用都是返回那个唯一的实例3 - 见 7 楼4 - Collection 是更抽象的接口“集合”,比如可以是 tree set, 可以是 hash map,也可以是 list 或者 array,它定义的只是所有“集合”都应该具备的行为
Collections.unmodifiableCollection 的作用相当于 defensive copy,加一层“壳”变成只读,只是不想让外部代码随意更改 Organization 的内部状态5 - 是,见 7 楼
DateJoined bean properties是什么不懂,其它我就按字面意思做,如下:
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());
}
}
}
唯一郁闷的是第一个题目说的“它包含仅一个叫做getMembers 的public method”,只能有一个公共的方法,那它添数据用反射写进去?还是每次加数据时候就强装类型,还是有现在没学习到的方法
虽然你结贴了,但是我刚学习完bean回来修正下前面自己写的不全面的,修正后如下:
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;
}
}