链接: 软件设计模式与体系结构实验——2.1-1(2)(抽象)工厂模式的应用
链接: 软件设计模式与体系结构实验——2.2-1生成器模式的应用
链接: 软件设计模式与体系结构实验——2.3-1单列模式的应用
【作业3.1-1】在例3.3的设计中,添加一个空军大队( Wing)类,该类与Squadron、Group类是平行的,因此应该继承了AirUnit类。该类的写法与Squadron或者Group类是类似的,所不同的是一个Wing有216中类型的飞机。具体要求以及代码实现参见光盘的相应作业部分。
(1)Wing类
package com.glut.xusheng;
/*=======================*/
/* Represents an air Wing */
/*=======================*/
public class Wing extends AirUnit{
public static final String FEATURES = "A Wing with 216 aircrafts";
Airforce[] fighters = new Airforce[162];
Airforce[] bombers = new Airforce[18];
Airforce[] transporters= new Airforce[18];
Airforce[] eAircrafts = new Airforce[18];
public Wing(){
for(int k=0;k<162;k++){
// need 162 fighters
}
for(int k=0;k<18;k++){
// need 18 bombers
}
for(int k=0;k<18;k++){
// need 18 transporters
}
for(int k=0;k<18;k++){
// need 18 eAirplanes
}
}
public String getDescription(){
return FEATURES;
}
public String fight(){
return super.fight();
}
}
(2)GUI类:
private String[] AirForceUnit = {"SQUADRON", "GROUP", "WING"};
add(1, 6, airCheckBox[13]);
else if ((m==13) && (ckBoxStates[13] == SELECTED)){
unit = new Wing();
airUnits.attach(unit);
unitInfo = unit.getDescription();
}
AirforceGUI类
package com.glut.xusheng;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Iterator;
/*===================================================================*/
/* User interface for Testing the Composite design pattern program */
/*===================================================================*/
public class AirforceGUI extends JFrame implements ItemListener{
private JScrollPane checkBoxPane, textPane;
private JSplitPane splitPane;
private JTextArea txtAirMission;
private JButton submitBtn, exitBtn;
private JPanel checkBoxPanel, btnPanel, choicePanel;
private JCheckBox[] airCheckBox;
private JCheckBox[] airUnitCheckBox;
private String[] airPlaneName ={"F-15E-Strike-Eagle","F-16C/D-Fighting-Falcon","F22A-Rapter",
"B-1B-Lancer","B-2A-Spirit","B-52H-Stratofortress",
"C-130E/H-Hercules","C-130J-Super-Hercules","CV-22B-Osprey",
"E-9A", "EC-130H/J-Compass", "AirForce","Fighters",
"Bombers", "Transporters", "E-Planes"};
//jia
private String[] AirForceUnit = {"SQUADRON", "GROUP", "WING"};
public final int SELECTED = ItemEvent.SELECTED;
public final int DESELECTED = ItemEvent.DESELECTED;
private static final String[] OPTION = {"Solo", "Group"};
private JComboBox[] optComoBox=new JComboBox[11];
private int[] ckBoxStates;
private GridBagLayout gridbag = new GridBagLayout();
private GridBagConstraints gbc = new GridBagConstraints();
public AirforceGUI(){
super("Composite Pattern - Airforce");
ckBoxStates = new int[50];
setUpChoicePanel();
setUpScrollPanes();
}
private void setUpChoicePanel(){
submitBtn = new JButton("Submit");
exitBtn = new JButton("Exit");
submitBtn.addActionListener( new ButtonActionListener());
exitBtn.addActionListener( new ButtonActionListener());
JPanel btnPanel =new JPanel();
btnPanel.add(submitBtn);
btnPanel.add(exitBtn);
int numCheckBox = airPlaneName.length;
airCheckBox = new JCheckBox[numCheckBox];
airUnitCheckBox = new JCheckBox[3];
//Check boxes for selection of the airplanes
for(int m=0; m<numCheckBox; m++){
airCheckBox[m]= new JCheckBox(airPlaneName[m]);
airCheckBox[m].setMnemonic(KeyEvent.VK_C);
airCheckBox[m].addItemListener(this);
}
//Check boxes for selection of air units
for(int m=0; m<3; m++){
airUnitCheckBox[m]= new JCheckBox(AirForceUnit[m]);
airUnitCheckBox[m].setMnemonic(KeyEvent.VK_C);
airUnitCheckBox[m].addItemListener(this);
}
//Combobox for deciding on solo flight or not
for(int i=0;i<11;i++){
optComoBox[i]= new JComboBox(OPTION);
optComoBox[i].addItemListener(this);
}
checkBoxPanel = new JPanel();
checkBoxPanel.setLayout(gridbag);
for(int m=0; m<numCheckBox; m++)
checkBoxPanel.add(airCheckBox[m]);
for(int m=0; m<3; m++)
checkBoxPanel.add(airUnitCheckBox[m]);
for(int i=0;i<11;i++)
checkBoxPanel.add(optComoBox[i]);
gbc.insets.top = 0;
gbc.insets.bottom = 0;
gbc.insets.left = 0;
gbc.insets.right = 0;
gbc.anchor = GridBagConstraints.WEST;
add(0, 0, airCheckBox[11]);
add(1, 1, airCheckBox[12]);
add(2, 3, airCheckBox[0]);
add(2, 4, airCheckBox[1]);
add(2, 5, airCheckBox[2]);
//
add(1, 6, airCheckBox[13]);
add(2, 7, airCheckBox[3]);
add(2, 8, airCheckBox[4]);
add(2, 9, airCheckBox[5]);
add(1, 10, airCheckBox[14]);
add(2, 11, airCheckBox[6]);
add(2, 12, airCheckBox[7]);
add(2, 13, airCheckBox[8]);
add(1, 14, airCheckBox[15]);
add(2, 15, airCheckBox[9]);
add(2, 16, airCheckBox[10]);
add(3, 3, optComoBox[0]);
add(3, 4, optComoBox[1]);
add(3, 5, optComoBox[2]);
add(3, 7, optComoBox[3]);
add(3, 8, optComoBox[4]);
add(3, 9, optComoBox[5]);
add(3, 11, optComoBox[6]);
add(3, 12, optComoBox[7]);
add(3, 13, optComoBox[8]);
add(3, 15, optComoBox[9]);
add(3, 16, optComoBox[10]);
add(0, 17, airUnitCheckBox[0]);
add(0, 18, airUnitCheckBox[1]);
add(0, 19, airUnitCheckBox[2]);
choicePanel = new JPanel();
choicePanel.setMinimumSize(new Dimension(500, 300));
choicePanel.setLayout(new BorderLayout());
choicePanel.add(checkBoxPanel, "Center");
choicePanel.add(btnPanel, "South");
}
private void add(int m, int n, JComponent com ){
gbc.gridx = m;
gbc.gridy = n;
gridbag.setConstraints(com, gbc);
}
private void setUpScrollPanes(){
txtAirMission = new JTextArea(3,10);
txtAirMission.setBackground(Color.cyan);
txtAirMission.setText("选择军事单位:空军中队(SQUADRON),空军团(GROUP)或者空军大队(WING)"
+ "\n组成固定单位的战斗力量。你也可以直接选择各种机型形成临时的编队"
+"\n飞行(在组合框中选Group)或者单飞(在组合框中选Solo)。");
checkBoxPane = new JScrollPane(choicePanel);
textPane = new JScrollPane(txtAirMission);
textPane.setMinimumSize(new Dimension(500, 100));
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, checkBoxPane, textPane);
splitPane.setDividerLocation(470);
getContentPane().add(splitPane);
setSize(new Dimension(500, 500));
setVisible(true);
}
//========================================
// 新增加功能,需要理解本监听器所涉及的方法。
//========================================
class ButtonActionListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
txtAirMission.setText("\n===Airforce New Mission===\n");
createAirGroup(e);
}
}
public void itemStateChanged(ItemEvent e){
Object source = e.getItemSelectable();
int state = e.getStateChange();
if (source == airCheckBox[11]) {
if(state == SELECTED){
for(int m=12; m<16; m++)
airCheckBox[m].setSelected(true);
}
else if (state == DESELECTED){
for(int m=12; m<16; m++)
airCheckBox[m].setSelected(false);
}
}
else if (source == airCheckBox[12]) {
if(state == SELECTED){
for(int m=0; m<3; m++)
airCheckBox[m].setSelected(true);
}
else if (state == DESELECTED){
for(int m=0; m<3; m++)
airCheckBox[m].setSelected(false);
}
}
else if (source == airCheckBox[0])
ckBoxStates[0]=state;
else if (source == airCheckBox[1])
ckBoxStates[1]=state;
else if (source == airCheckBox[2])
ckBoxStates[2]=state;
else if (source == airCheckBox[13]){
if(state == SELECTED){
for(int m=3; m<6; m++)
airCheckBox[m].setSelected(true);
}
else if (state == DESELECTED){
for(int m=3; m<6; m++)
airCheckBox[m].setSelected(false);
}
}
else if (source == airCheckBox[3])
ckBoxStates[3]=state;
else if (source == airCheckBox[4])
ckBoxStates[4]=state;
else if (source == airCheckBox[5])
ckBoxStates[5]=state;
else if (source == airCheckBox[14]){
if(state == SELECTED){
for(int m=6; m<9; m++)
airCheckBox[m].setSelected(true);
}
else if (state == DESELECTED){
for(int m=6; m<9; m++)
airCheckBox[m].setSelected(false);
}
}
else if (source == airCheckBox[6])
ckBoxStates[6]=state;
else if (source == airCheckBox[7])
ckBoxStates[7] = state;
else if (source == airCheckBox[8])
ckBoxStates[8]=state;
else if (source == airCheckBox[15]){
if(state == SELECTED){
airCheckBox[9].setSelected(true);
airCheckBox[10].setSelected(true);
}
else if (state == DESELECTED){
airCheckBox[9].setSelected(false);
airCheckBox[10].setSelected(false);
}
}
else if (source == airCheckBox[9])
ckBoxStates[9]=state;
else if (source == airCheckBox[10])
ckBoxStates[10]=state;
//== for air units
else if (source == airUnitCheckBox[0])
ckBoxStates[11]=state;
else if (source == airUnitCheckBox[1])
ckBoxStates[12]=state;
else if (source == airUnitCheckBox[2])
ckBoxStates[13]=state;
}
private void createAirGroup(ActionEvent e){
Airforce airCraft = null;
Airforce unit = null;
AirUnit airGroup = new AirUnit();
AirUnit airUnits = new AirUnit();
boolean isSolo = false;
int len = ckBoxStates.length;
String unitInfo = null;
if (e.getActionCommand().equals("Submit")) {
for(int m = 0; m < len; m++ ){
if ((m==0) && (ckBoxStates[0] == SELECTED)) {
airCraft = new F15();
if(optComoBox[0].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==1) && (ckBoxStates[1] == SELECTED)){
airCraft = new F16();
if(optComoBox[1].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==2) && (ckBoxStates[2] == SELECTED)){
airCraft = new F22();
if(optComoBox[2].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==3) && (ckBoxStates[3] == SELECTED)){
airCraft = new B1B();
if(optComoBox[3].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==4) && (ckBoxStates[4] == SELECTED)) {
airCraft = new B2A();
if(optComoBox[4].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==5) && (ckBoxStates[5] == SELECTED)){
airCraft = new B52();
if(optComoBox[5].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==6) && (ckBoxStates[6] == SELECTED)) {
airCraft = new C130E();
if(optComoBox[6].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==7) && (ckBoxStates[7] == SELECTED)) {
airCraft = new C130J();
if(optComoBox[7].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==8) && (ckBoxStates[8] == SELECTED)) {
airCraft = new CV22();
if(optComoBox[8].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==9) && (ckBoxStates[9] == SELECTED)) {
airCraft = new E9A();
if(optComoBox[9].getSelectedItem().equals("Solo"))
isSolo = true;
}
else if ((m==10) && (ckBoxStates[10] == SELECTED)) {
airCraft = new EC130();
if(optComoBox[10].getSelectedItem().equals("Solo"))
isSolo = true;
}
//== for air units
else if ((m==11) && (ckBoxStates[11] == SELECTED)){
unit = new Squadron();
airUnits.attach(unit);
unitInfo = unit.getDescription();
}
else if ((m==12) && (ckBoxStates[12] == SELECTED)){
unit = new Group();
airUnits.attach(unit);
unitInfo = unit.getDescription();
}
else if ((m==13) && (ckBoxStates[13] == SELECTED)){
unit = new Wing();
airUnits.attach(unit);
unitInfo = unit.getDescription();
}
if( airCraft != null){
if(isSolo == false)
airGroup.attach(airCraft);
else{
String f = airCraft.fight();
txtAirMission.append("Solo Flight Mission: \n" + f + "\n");
}
airCraft = null;
isSolo = false;
}
} //end for loop
//Display Air Group Actions
if(airGroup.getSize() > 0){
String str = airGroup.fight();
txtAirMission.append("Mission with newly-formed unit: \n" + str + "\n");
}
if(airUnits.getSize() > 0){
String str = airUnits.fight();
txtAirMission.append("Mission with fixed unit: \n" + unitInfo + " \n");
txtAirMission.append("Aircrafts in this mission: \n" + str + "\n");
}
}
else if (e.getActionCommand().equals("Exit")) {
System.exit(1);
}
}
public static void main(String args[]){
try {
JFrame.setDefaultLookAndFeelDecorated(true);
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch (Exception evt) {}
AirforceGUI frame = new AirforceGUI();
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
frame.setSize(500, 600);
frame.setVisible(true);
}
}
Airforce类
package com.glut.xusheng;
/*===================================*/
/* This is the interface of a class */
/* hierarchy that is to be visited */
/* by some visitors */
/*===================================*/
public abstract interface Airforce {
public abstract String fight();
public abstract String getDescription();
}
AirUnit类
package com.glut.xusheng;
import java.util.ArrayList;
import java.util.Iterator;
/*=====================================*/
/* This is the object structure class */
/* in the class diagram of the visitor */
/* design pattern */
/*=====================================*/
public class AirUnit implements Airforce{
private ArrayList<Airforce> parts;
private String answer="";
private String FEATURES = "Air Formation of Airforce. ";
public AirUnit(){
parts = new ArrayList<Airforce>();
}
public void attach(Airforce equip){
if(equip != null)
parts.add(equip);
}
public void detach(Airforce equip){
if(equip != null)
parts.remove(equip);
}
public Iterator<Airforce> elements(){
return parts.iterator();
}
public String fight(){
int len =parts.size();
for (int i=0; i < len; i++){
Airforce part = parts.get(i);
answer = answer + part.fight()+"\n";
}
return answer;
}
public int getSize(){
return parts.size();
}
public String getDescription(){
return FEATURES;
}
}
B1B类
package com.glut.xusheng;/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class B1B extends Bomber{
public static final String FEATURES = "B1B Lancer";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
B2A类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class B2A extends Bomber{
public static final String FEATURES = "B2A Spirit";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
B52类
package com.glut.xusheng;
public class B52 extends Bomber{
public static final String FEATURES = "B52H StratoFortress";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
Bomber类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public abstract class Bomber implements Airforce{
public static final String FEATURES = "Bombers ";
public String getDescription(){
return FEATURES;
}
public abstract String fight();
}
C130E类
package com.glut.xusheng;
public class C130E extends Transporter{
public static final String FEATURES = "C130EH Hercules";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
C130J类
package com.glut.xusheng;
public class C130J extends Transporter{
public static final String FEATURES = "C130J Super Hercules";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
CV22类
package com.glut.xusheng;
public class CV22 extends Transporter{
public static final String FEATURES = "CV22BO Sprey";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
E9A类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class E9A extends EPlane{
public static final String FEATURES = "E9A ";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
EC130类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class EC130 extends EPlane{
public static final String FEATURES = "EC130HJ Compass";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
EPlane类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public abstract class EPlane implements Airforce{
public static final String FEATURES = "EPlanes ";
public String getDescription(){
return FEATURES;
}
public abstract String fight();
}
F15类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class F15 extends Fighter{
public static final String FEATURES = "F15E Strike Eagle";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
F16类
package com.glut.xusheng;/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class F16 extends Fighter{
public static final String FEATURES = "F16CD Fighting Falcon";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
F22类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public class F22 extends Fighter{
public static final String FEATURES = "F22A Rapter";
public String getDescription(){
return FEATURES;
}
public String fight(){
return FEATURES + " Ready to fight!";
}
}
Fighter类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public abstract class Fighter implements Airforce{
public static final String FEATURES = "Fighter Airplanes";
public String getDescription(){
return FEATURES;
}
public abstract String fight();
}
Group类
package com.glut.xusheng;/*=======================*/
/* Represents an air Group */
/*=======================*/
public class Group extends AirUnit{
public static final String FEATURES = "A Group with 72 aircrafts";
Airforce[] fighters = new Airforce[54];
Airforce[] bombers = new Airforce[6];
Airforce[] transporters= new Airforce[6];
Airforce[] eAircrafts = new Airforce[6];
public Group(){
for(int k=0;k<54;k++){
fighters[k] = new F22();
super.attach(fighters[k]);
}
for(int k=0;k<6;k++){
bombers[k] = new B52();
super.attach(bombers[k] );
}
for(int k=0;k<6;k++){
transporters[k] = new C130J();
super.attach(transporters[k]);
}
for(int k=0;k<6;k++){
eAircrafts[k] = new E9A();
super.attach(eAircrafts[k]);
}
}
public String getDescription(){
return FEATURES;
}
public String fight(){
return super.fight();
}
}
Squadron类
package com.glut.xusheng;
/*==========================*/
/* Represents an air Squadron */
/*==========================*/
public class Squadron extends AirUnit{
public static final String FEATURES = "A Quadron with 24 aircrafts";
Airforce[] fighters = new Airforce[18];
Airforce[] bombers = new Airforce[2];
Airforce[] transporters= new Airforce[2];
Airforce[] eAircrafts = new Airforce[2];
public Squadron(){
for(int k=0;k<18;k++){
fighters[k] = new F22();
super.attach(fighters[k]);
}
for(int k=0;k<2;k++){
bombers[k] = new B52();
super.attach(bombers[k] );
}
for(int k=0;k<2;k++){
transporters[k] = new C130J();
super.attach(transporters[k]);
}
for(int k=0;k<2;k++){
eAircrafts[k] = new E9A();
super.attach(eAircrafts[k]);
}
}
public String getDescription(){
return FEATURES;
}
public String fight(){
return super.fight();
}
}
Transporter类
package com.glut.xusheng;
/*================================*/
/* Represents a kind of airforce */
/*================================*/
public abstract class Transporter implements Airforce{
public static final String FEATURES = "Transporters ";
public String getDescription(){
return FEATURES;
}
public abstract String fight();
}
(1)组合(Composite Pattern)模式的定义:
有时又叫作整体-部分(Part-Whole)模式,它是一种将对象组合成树状的层次结构的模式,用来表示“整体-部分”的关系,使用户对单个对象和组合对象具有一致的访问性,属于结构型设计模式。
组合模式一般用来描述整体与部分的关系,它将对象组织到树形结构中,顶层的节点被称为根节点,根节点下面可以包含树枝节点和叶子节点,树枝节点下面又可以包含树枝节点和叶子节点,树形结构图如下。
组合模式共分为三种角色:
1.Component(抽象构件):叶子构件与容器构件共同继承的父类或者是共同实现的接口,该角色中包含所有子类共有方法的声明和实现,在抽象构件中定义了管理子构件的方法,新增构件、删除构件、获取构件。
2.Leaf(叶子构件):表示叶子节点,没有子节点,对于继承父类的管理子节点的方法以抛出异常的方式处理。
3.Composite(容器构件):表示容器节点,包含子节点,子节点可以是容器节点也可以是叶子节点,其提供一个集合来对子节点进行维护,以迭代的方式对子节点进行处理。
组合模式的关键是抽象构件类,它既可以表示叶子节点也可以表示容器节点,对于客户端而言是统一对抽象构件进行处理的,抽象构件类和容器构件类是聚合关联的关系,抽象构件类是容器构件类的一部分,这样容器构件类对子构件进行处理时不用区分是叶子节点还是容器节点,能够统一的做处理。
(2)组合模式的注意事项和细节:
1.简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。
2.具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动.
3.方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构。
4.需要遍历组织机构,或者处理的对象具有树形结构时, 非常适合使用组合模式。
5.要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式。