实验目的
1 掌握外观模式(Facade)的特点
2 分析具体问题,使用外观模式进行设计。
实验内容和要求
作业3.3-1
在光盘的附加例子3.3的设计中,添加一个新的Tuition(学费)类。该类负责从一个文件中读出学生的学费缴纳情况。该类已经写好,与其他类在同一个文件夹中。要求在外观类StudentInfoFacade中实现extractTuitionInfo()方法,并且在该类合适的地方调用该方法,以便实现在用户界面,除了显示学生基本信息、学习科目与成绩、获奖情况的同时,也显示学生各学期的学费缴纳情况。具体要求与代码参见书后光盘的作业部分。
【模式代码(JAVA语言实现)】
AcademicRecord.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
public class AcademicRecord {
private String firstName;
private String lastName;
private String studNum;
//private String courseName;
//private String courseNumber;
//private String courseScore;
private String aFile;
private ArrayList<StudentAcademicModel> allScores;
//constructor
public AcademicRecord(String firstName, String lastName, String studNum ) {
this.firstName = firstName;
this.lastName = lastName;
this.studNum = studNum;
}
//Get basic student academic information from a text file that is
//passed in from the parameter
public ArrayList<StudentAcademicModel> getAllScores(String file){
aFile = file;
allScores = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(aFile));
String line = reader.readLine();
while(line != null) {
if (line.length() != 0) {
String[] arr = line.split("\\,");
StudentAcademicModel sdam = new StudentAcademicModel (arr[0].trim(), arr[1].trim(),
arr[2].trim(), arr[3].trim(),
arr[4].trim(), arr[5].trim());
if( sdam.getStudFirstName().equals(firstName) &&
sdam.getStudLastName().equals(lastName) &&
sdam.getStudSerialNum().equals(studNum) )
allScores.add(sdam);
}
line = reader.readLine();
}
}
catch(FileNotFoundException exc){
exc.printStackTrace();
System.exit(1);
}
catch(IOException exc){
exc.printStackTrace();
System.exit(1);
}
return allScores;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getStudNumber() {
return studNum;
}
}
Award.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
public class Award {
private String firstName;
private String lastName;
private String studNum;
private String aFile;
private ArrayList<StudentAwardModel> allAwards;
//constructor
public Award(String fname, String lname, String stuNum) {
firstName = fname;
lastName = lname;
studNum = stuNum;
}
//Get basic student awards information from a text file that is
//passed in from the parameter
public ArrayList<StudentAwardModel> getAllAwards(String file){
aFile = file;
allAwards = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(aFile));
String line = reader.readLine();
while(line != null) {
if (line.length() != 0) {
String[] arr = line.split("\\,");
StudentAwardModel sdam = new StudentAwardModel (arr[0].trim(), arr[1].trim(),
arr[2].trim(),arr[3].trim(),
arr[4].trim());
if( sdam.getStudFirstName().equals(firstName) &&
sdam.getStudLastName().equals(lastName) &&
sdam.getStudSerialNum().equals(studNum) )
allAwards.add(sdam);
}
line = reader.readLine();
}
}
catch(FileNotFoundException exc){
exc.printStackTrace();
System.exit(1);
}
catch(IOException exc){
exc.printStackTrace();
System.exit(1);
}
return allAwards;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getStudNumber() {
return studNum;
}
}
ClientGUI.java
public class ClientGUI extends JFrame {
private JSplitPane bigSplitPane;
private JScrollPane showInfoPane;
private JPanel btnPanel;
private JComboBox cmbAlgorithm, cmbHouseType;
private JLabel lblFirstName;
private JLabel lblLastName;
private JLabel lblSerialNum;
private Dimension minimumSize;
private JTextArea txtStudentInfo;
private JTextField txtFirstName;
private JTextField txtLastName;
private JTextField txtSerialNum;
private StudentInfoFacade infoFacade;
public static final String PRINT = "Print";
public static final String EXIT = "Exit";
public ClientGUI() {
super("Facade Pattern- Student information system ");
minimumSize = new Dimension(130, 100);
setUpChoicePanel();
setUpScrollPanes();
}
private void setUpChoicePanel() {
JLabel lblToBeSorted = new JLabel("Input Integers");
txtFirstName = new JTextField(20);
txtLastName = new JTextField(20);
txtSerialNum = new JTextField(20);
lblFirstName = new JLabel("First Name");
lblLastName = new JLabel("Last Name");
lblSerialNum = new JLabel("Serial Number");
//Create buttons
JButton openButton = new JButton(PRINT);
openButton.setMnemonic(KeyEvent.VK_S);
JButton exitButton = new JButton(EXIT);
exitButton.setMnemonic(KeyEvent.VK_X);
ButtonListener btnListener = new ButtonListener();
// add action Listener
openButton.addActionListener(btnListener);
exitButton.addActionListener(btnListener);
btnPanel = new JPanel();
//------------------------------------------------
GridBagLayout gridbag = new GridBagLayout();
btnPanel.setLayout(gridbag);
GridBagConstraints gbc = new GridBagConstraints();
btnPanel.add(lblFirstName);
btnPanel.add(lblLastName);
btnPanel.add(lblSerialNum);
btnPanel.add(txtFirstName);
btnPanel.add(txtLastName);
btnPanel.add(txtSerialNum);
btnPanel.add(openButton);
btnPanel.add(exitButton);
gbc.insets.top = 5;
gbc.insets.bottom = 5;
gbc.insets.left = 5;
gbc.insets.right = 5;
gbc.gridx = 0;
gbc.gridy = 0;
gridbag.setConstraints(lblFirstName, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gridbag.setConstraints(txtFirstName, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gridbag.setConstraints(lblLastName, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gridbag.setConstraints(txtLastName, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gridbag.setConstraints(lblSerialNum, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gridbag.setConstraints(txtSerialNum, gbc);
gbc.insets.left = 2;
gbc.insets.right = 2;
gbc.insets.top = 15;
gbc.gridx = 0;
gbc.gridy = 7;
gridbag.setConstraints(openButton, gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx = 1;
gbc.gridy = 7;
gridbag.setConstraints(exitButton, gbc);
//-----------------------------------------------
}
private void setUpScrollPanes() {
Border raisedbevel = BorderFactory.createRaisedBevelBorder();
txtStudentInfo = new JTextArea("Student report: \n", 20, 30);
txtStudentInfo.setFont(new Font("Helvetica", Font.BOLD, 12));
txtStudentInfo.setBackground(Color.cyan);
showInfoPane = new JScrollPane(txtStudentInfo);
bigSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, btnPanel, showInfoPane);
bigSplitPane.setDividerLocation(230);
getContentPane().add(bigSplitPane);
setSize(new Dimension(500, 400));
setVisible(true);
}
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals(EXIT)) {
System.exit(1);
}
if (ae.getActionCommand().equals(PRINT)) {
String firstName = txtFirstName.getText().trim();
String lastName = txtLastName.getText().trim();
String studentNum = txtSerialNum.getText().trim();
infoFacade = new StudentInfoFacade(firstName, lastName, studentNum);
String studentInfo = infoFacade.getStudentInfo();
txtStudentInfo.append(" " + studentInfo + " \n");
}
}
}
public static void main(String args[]) {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (Exception evt) {
}
ClientGUI frame = new ClientGUI();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
frame.setSize(500, 400);
frame.setVisible(true);
}
}
StudentAcademicModel.java
public class StudentAcademicModel {
private String studFirstName;
private String studLastName;
private String studSerialNum;
private String courseTitle;
private String courseNum;
private String score;
public StudentAcademicModel (String studFirstName, String studLastName, String studSerialNum,
String courseTitle, String courseNum, String score) {
this.studFirstName = studFirstName;
this.studLastName = studLastName;
this.studSerialNum = studSerialNum;
this.courseTitle = courseTitle;
this.courseNum = courseNum;
this.score=score;
}
public String getStudFirstName() {
return studFirstName;
}
public String getStudLastName() {
return studLastName;
}
public String getStudSerialNum() {
return studSerialNum;
}
public String getCourseTitle() {
return courseTitle;
}
public String getCourseNum() {
return courseNum;
}
public String getScore() {
return score;
}
}
StudentAwardModel.java
public class StudentAwardModel {
private String studFirstName;
private String studLastName;
private String studSerialNum;
private String awardName;
private String awardDate;
public StudentAwardModel (String studFirstName, String studLastName, String studSerialNum,
String awardName, String awardDate) {
this.studFirstName = studFirstName;
this.studLastName = studLastName;
this.studSerialNum = studSerialNum;
this.awardName = awardName;
this.awardDate = awardDate;
}
public String getStudFirstName() {
return studFirstName;
}
public String getStudLastName() {
return studLastName;
}
public String getStudSerialNum() {
return studSerialNum;
}
public String getAwardName() {
return awardName;
}
public String getAwardDate() {
return awardDate;
}
}
StudentBasicInfo.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
public class StudentBasicInfo {
private String name;
private String birthDate;
private String serialNum;
private ArrayList<StudentBasicInfoModel> student;
final static String STUDENT_BASIC_INFO = "StudentBasicInfo.txt";
//Constructor
public StudentBasicInfo (String name, String birthDate, String serialNum) {
this.name = name;
this.birthDate = birthDate;
this.serialNum = serialNum;
}
//Check if the student name is in the student list or not
public static boolean isExistingStudentName(String name) {
boolean flag = false;
ArrayList<StudentBasicInfoModel> student = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(STUDENT_BASIC_INFO));
String line = reader.readLine();
while(line != null) {
if (line.length() != 0) {
String[] arr = line.split("\\,");
if( arr[0].trim().equals(name))
flag = true;
}
line = reader.readLine();
}
}
catch(FileNotFoundException exc){
exc.printStackTrace();
System.exit(1);
}
catch(IOException exc){
exc.printStackTrace();
System.exit(1);
}
return flag;
}
//Get basic student information from STUDENT_BASIC_INFO
//and return it with type ArrayList
public ArrayList<StudentBasicInfoModel> getStudentBasicInfo(){
student = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(STUDENT_BASIC_INFO));
String line = reader.readLine();
while(line != null) {
if (line.length() != 0) {
String[] arr = line.split("\\,");
StudentBasicInfoModel bsim = new StudentBasicInfoModel (arr[0].trim(), arr[1].trim(),
arr[2].trim(),arr[3].trim(),
arr[4].trim(), arr[5].trim());
if( bsim.getName().equals(name) && bsim.getSerialNum().equals(serialNum) )
student.add(bsim);
}
line = reader.readLine();
}
}
catch(FileNotFoundException exc){
exc.printStackTrace();
System.exit(1);
}
catch(IOException exc){
exc.printStackTrace();
System.exit(1);
}
return student;
}
public String getName() {
return name;
}
public String getBirthDate() {
return birthDate;
}
public String getSerialNum() {
return serialNum;
}
}
StudentBasicInfoModel.java
public class StudentBasicInfoModel{
private String name;
private String birthDate;
private String serialNumber;
private String ssNumber;
private String major;
private String degree;
public StudentBasicInfoModel(String name, String birthDate, String serialNumber,
String ssNumber, String major, String degree) {
this.name = name;
this.birthDate = birthDate;
this.serialNumber = serialNumber;
this.ssNumber = ssNumber;
this.major = major;
this.degree = degree;
}
public String getName() {
return name;
}
public String getBirthDate() {
return birthDate;
}
public String getSerialNum() {
return serialNumber;
}
public String getSocialSecurityNum() {
return ssNumber;
}
public String getMajor() {
return major;
}
public String getDegree() {
return degree;
}
}
StudentInfoFacade.java
import java.util.ArrayList;
import java.util.Iterator;
public class StudentInfoFacade {
private String firstName;
private String lastName;
private String studentNum;
private StudentBasicInfo studentInfo;
private AcademicRecord academicRecord;
private Award award;
private Tuition tuition;
private final String AWARDS = "StudentAward.txt";
private final String RECORDS = "StudentAcademicRecord.txt";
public StudentInfoFacade(String firstName, String lastName, String studentNum) {
this.firstName = firstName;
this.lastName = lastName;
this.studentNum = studentNum;
}
// Get comprehensive student information by calling 3 methods
// in this class, including basic student information, student
// academic records, and possible awards info. Client class can
// just call this method to get all the information.
public String getStudentInfo() {
String nm = firstName + " " + lastName;
if (StudentBasicInfo.isExistingStudentName(nm) == false) {
String msg = "The student with the name doesn't exist.";
return msg;
}
String allInfo = null;
String info = extractStudentInfo();
String record = extractAcademicRecord();
String awards = extractAllAwards();
//add codes
String tuitionInfo = extractTuitionInfo();
allInfo = "\nBasic Student Info: \n" + info + "\nAcademic record: \n" + record + "\nAwards: \n" + awards + "\nTuition: \n" + tuitionInfo;
return allInfo;
}
//Extract basic student information from a file, which is called from
//class StudentBasicInfo
public String extractStudentInfo() {
String allInfo = " ";
String name = firstName + " " + lastName;
studentInfo = new StudentBasicInfo(name, "1600", studentNum);
ArrayList<StudentBasicInfoModel> basicInfo = studentInfo.getStudentBasicInfo();
Iterator infoIterator = basicInfo.iterator();
while (infoIterator.hasNext()) {
StudentBasicInfoModel infoModel = (StudentBasicInfoModel) infoIterator.next();
String nm = infoModel.getName().trim();
String birth = infoModel.getBirthDate().trim();
String studNum = infoModel.getSerialNum().trim();
String ssn = infoModel.getSocialSecurityNum().trim();
String mj = infoModel.getMajor().trim();
String degree = infoModel.getDegree().trim();
allInfo = allInfo + " " + nm + " " + birth + " " + studNum + " " + ssn + " " + mj + " " + degree + "\n";
}
return allInfo;
}
//Extract academic records from text file RECORDS, accessed from this method
public String extractAcademicRecord() {
String allInfo = " ";
academicRecord = new AcademicRecord(firstName, lastName, studentNum);
ArrayList<StudentAcademicModel> records = academicRecord.getAllScores(RECORDS);
Iterator recordIterator = records.iterator();
while (recordIterator.hasNext()) {
StudentAcademicModel recordModel = (StudentAcademicModel) recordIterator.next();
String name = recordModel.getStudFirstName().trim();
String birth = recordModel.getStudLastName().trim();
String studNum = recordModel.getStudSerialNum().trim();
String coarseName = recordModel.getCourseTitle().trim();
String courseNo = recordModel.getCourseNum().trim();
String score = recordModel.getScore().trim();
allInfo = allInfo + " " + name + " " + birth + " " + studNum + " " + coarseName + " " + courseNo + " " + score + "\n";
}
return allInfo;
}
//Extract student awards from text file AWARDS, accessed from this method
public String extractAllAwards() {
String allInfo = " ";
award = new Award(firstName, lastName, studentNum);
ArrayList<StudentAwardModel> awd = award.getAllAwards(AWARDS);
Iterator awardIterator = awd.iterator();
while (awardIterator.hasNext()) {
StudentAwardModel awardModel = (StudentAwardModel) awardIterator.next();
String firstNm = awardModel.getStudFirstName().trim();
String lastNm = awardModel.getStudLastName().trim();
String studNum = awardModel.getStudSerialNum().trim();
String awardName = awardModel.getAwardName().trim();
String awadDate = awardModel.getAwardDate().trim();
allInfo = allInfo + " " + firstNm + " " + lastNm + " " + studNum + " " + awardName + " " + awadDate + "\n";
}
return allInfo;
}
// Students are supposed to finish this homework
public String extractTuitionInfo() {
String allInfo = " ";
Tuition tuition = new Tuition(firstName, lastName, studentNum);
ArrayList<String> studentTuitionInfo = tuition.getStudentTuitionInfo();
Iterator<String> iterator = studentTuitionInfo.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
allInfo += (next + "\n");
}
// Students are supposed to finish this part
return allInfo;
}
}
添加类Tuition.java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
public class Tuition {
private String firstName;
private String lastName;
private String studNum;
private final String STUDENT_TUITION_FILE = "Tuition.txt";
private ArrayList<String> studentTuition;
//constructor
public Tuition(String fname, String lname, String stuNum) {
firstName = fname;
lastName = lname;
studNum = stuNum;
}
//Get tuition information paid by students
public ArrayList<String> getStudentTuitionInfo() {
studentTuition = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(STUDENT_TUITION_FILE));
String line = reader.readLine();
while (line != null) {
if (line.length() != 0) {
String[] arr = line.split("\\,");
if (arr[0].trim().equals(firstName) && arr[1].trim().equals(lastName) && arr[2].trim().equals(studNum))
studentTuition.add(line);
}
line = reader.readLine();
}
} catch (FileNotFoundException exc) {
exc.printStackTrace();
System.exit(1);
} catch (IOException exc) {
exc.printStackTrace();
System.exit(1);
}
return studentTuition;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getStudNumber() {
return studNum;
}
}
【实验小结】
通过本次实验,学会了使用外观模式。外观方法模式的适用性如下:
1)当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式。
2)客户端程序与多个子系统之间存在很大的依赖性。引入外观类可以将子系统与客户端解耦,从而提高子系统的独立性和可移植性。
3)在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。