资源描述
设计模式实验二
实 验 报 告 书
专业班级 软 件 0703
学 号 3901070324
姓 名 吉亚云
指导老师 刘 伟
时 间 2010年4月 24日
中南大学软件学院
实验二 设计模式上机实验二
一、实验目的
使用PowerDesigner和任意一种面向对象编程语言实现几种常用的设计模式,加深对这些模式的理解,包括装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式。
二、实验内容
使用PowerDesigner和任意一种面向对象编程语言实现装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式,包括根据实例绘制相应的模式结构图、编写模式实现代码,运行并测试模式实例代码。
三、实验要求
1. 正确无误绘制装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式的模式结构图;
2. 使用任意一种面向对象编程语言实现装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式,代码运行正确无误。
四、实验步骤
1. 使用PowerDesigner绘制装饰模式结构图并用面向对象编程语言实现该模式;
2. 使用PowerDesigner绘制外观模式结构图并用面向对象编程语言实现该模式;
3. 使用PowerDesigner绘制代理模式结构图并用面向对象编程语言实现该模式;
4. 使用PowerDesigner绘制职责链模式结构图并用面向对象编程语言实现该模式;
5. 使用PowerDesigner绘制命令模式结构图并用面向对象编程语言实现该模式;
6. 使用PowerDesigner绘制迭代器模式结构图并用面向对象编程语言实现该模式;
7. 使用PowerDesigner绘制观察者模式结构图并用面向对象编程语言实现该模式;
8. 使用PowerDesigner绘制状态模式结构图并用面向对象编程语言实现该模式;
9. 使用PowerDesigner绘制策略模式结构图并用面向对象编程语言实现该模式;
10. 使用PowerDesigner绘制模板方法模式结构图并用面向对象编程语言实现该模式。
五、实验报告要求
1. 提供装饰模式结构图及实现代码;
2. 提供外观模式结构图及实现代码;
3. 提供代理模式结构图及实现代码;
4. 提供职责链模式结构图及实现代码;
5. 提供命令模式结构图及实现代码;
6. 提供迭代器模式结构图及实现代码;
7. 提供观察者模式结构图及实现代码;
8. 提供状态模式结构图及实现代码;
9. 提供策略模式结构图及实现代码;
10. 提供模板方法模式结构图及实现代码。
六、实验结果
(1) 装饰模式
某图书管理系统中,书籍类(Book)具有借书方法borrowBook()和还书方法returnBook() 。现需要动态给书籍对象添加冻结方法freeze()和遗失方法lose()。使用装饰模式设计该系统,绘制类图并编程实现。
package DirectorPattern;
interface Book
{
void borrowBook();
void returnBook();
}
final class MyBook implements Book
{
public void borrowBook(){
System.out.println("MyBook borrowing!");
}
public void returnBook(){
System.out.println("MyBook returning!");
}
}
abstract class BookDirector implements Book
{
private Book book;
public BookDirector(Book book)
{
System.out.println("Book directoring!");
this.book=book;
}
public void borrowBook(){
book.borrowBook();
}
public void returnBook(){
book.returnBook();
}
}
class NewBook extends BookDirector
{
public NewBook(Book book)
{
super(book);
System.out.println("Book changed to NewBook!");
}
public void freeze()
{
System.out.println("Book freezing!");
}
public void lose()
{
System.out.println("Book lost!");
}
}
public class BookDirectorClient {
public static void main(String a[])
{
//半透明
Book book=new MyBook();
NewBook newBook=new NewBook(book);
newBook.borrowBook();
newBook.returnBook();
newBook.freeze();
newBook.lose();
}
}
运行结果:
(2) 外观模式
在电脑主机(Mainframe)中,只需要按下主机的开机按钮(on()),即可调用其他硬件设备和软件的启动方法,如内存(Memory)的自检(check()),CPU的运行(run()),硬盘(HardDisk)的读取(read()),操作系统(OS)的载入(load())等,如果某一过程发生错误则电脑启动失败。使用外观模式模拟该过程,绘制类图并编程实现。
package FacadePattern;
class Mainframe {
private Memory memory;
private CPU cpu;
private HardDisk disk;
private OS os;
public Mainframe()
{
memory=new Memory() ;
cpu=new CPU() ;
disk=new HardDisk() ;
os=new OS() ;
}
public void on()
{
memory.check();
cpu.run();
disk.read();
os.load();
}
public void off()
{
memory.off();
cpu.off();
disk.off();
os.off();
}
}
class Memory
{
public void check()
{
System.out.println( "Memory checking!");
}
public void off()
{
System.out.println("Memory off!");
}
}
class CPU
{
public void run()
{
System.out.println("CPU running!");
}
public void off()
{
System.out.println("CPU off!");
}
}
class HardDisk
{
public void read()
{
System.out.println("HardDisk reading!");
}
public void off()
{
System.out.println("HardDisk off!");
}
}
class OS
{
public void load()
{
System.out.println("OS loading!");
}
public void off()
{
System.out.println("OS off!");
}
}
public class ComputerFacadeClient
{
public static void main(String args[])
{
Mainframe mainframe=new Mainframe();
mainframe.on();
System.out.println("-----------------------");
mainframe.off();
}
}
运行结果:
(3) 代理模式
应用软件所提供的桌面快捷方式是快速启动应用程序的代理,桌面快捷方式一般使用一张小图片来表示(Picture),通过调用快捷方式的run()方法将调用应用软件(Application)的run()方法。使用代理模式模拟该过程,绘制类图并编程实现。
package ProxyPattern;
interface Software
{
void run();
}
class Application implements Software
{
public void run()
{
System.out.println("Application is running!");;
}
}
class Picture implements Software
{
private Application app=new Application();
public void run(){
app.run();
}
}
public class FastwayProxyClient
{
public static void main(String a[])
{
Software proxy=new Picture();
proxy.run();
}
}
运行结果:
(4) 职责链模式
某物资管理系统中物资采购需要分级审批,主任可以审批1万元及以下的采购单,部门经理可以审批5万元及以下的采购单,副总经理可以审批10万元及以下的采购单,总经理可以审批20万元及以下的采购单,20万元以上的采购单需要开会确定。现使用职责链模式设计该系统,绘制类图并编程实现。
package ChainResponsibilityPattern;
class ShoppingRequest
{
private String shoppingReason;
private double billMoney;
public ShoppingRequest(String shoppingReason,double billMoney)
{
this.shoppingReason=shoppingReason;
this.billMoney=billMoney;
}
public String getShoppingReason() {
return shoppingReason;
}
public void setShoppingReason(String shoppingReason) {
this.shoppingReason = shoppingReason;
}
public double getBillMoney() {
return billMoney;
}
public void setBillMoney(double billMoney) {
this.billMoney = billMoney;
}
}
//抽象领导
abstract class Leader
{
protected String name;
//上级领导
protected Leader successor;
public Leader(String name)
{
this.name=name;
}
public void setSuccessor(Leader successor)
{
this.successor=successor;
}
public abstract void handleRequest(ShoppingRequest request);
}
//主任
class Director extends Leader
{
public Director(String name)
{
super(name);
}
public void handleRequest(ShoppingRequest request)
{
if(request.getBillMoney()<10000.00)
{
System.out.println("主任" + name + "处理物资采购:" + request.getShoppingReason() + ",批准采购资金为:" + request.getBillMoney() + "RMB");
}
else
{
if(this.successor!=null)
{
this.successor.handleRequest(request);
}
}
}
}
//部门经理
class DepartmentManager extends Leader
{
public DepartmentManager(String name)
{
super(name);
}
public void handleRequest(ShoppingRequest request)
{
if(request.getBillMoney()<50000.00)
{
System.out.println("部门经理" + name + "处理物资采购:" + request.getShoppingReason() + ",批准采购资金为:" + request.getBillMoney() + "RMB");
}
else
{
if(this.successor!=null)
{
this.successor.handleRequest(request);
}
}
}
}
//副经理
class ViceManager extends Leader
{
public ViceManager(String name)
{
super(name);
}
public void handleRequest(ShoppingRequest request)
{
if(request.getBillMoney()<100000.00)
{
System.out.println("副经理" + name + "处理物资采购:" + request.getShoppingReason() + ",批准采购资金为:" + request.getBillMoney() + "RMB");
}
else
{
if(this.successor!=null)
{
this.successor.handleRequest(request);
}
}
}
}
//总经理
class GeneralManager extends Leader
{
public GeneralManager(String name)
{
super(name);
}
public void handleRequest(ShoppingRequest request)
{
if(request.getBillMoney()<200000.00)
{
System.out.println("总经理" + name + "处理物资采购:" + request.getShoppingReason() + ",批准采购资金为:" + request.getBillMoney() + "RMB");
}
else
{
System.out.println("董事会将开会处理物资采购:" + request.getShoppingReason() + ",批准采购资金为:" + request.getBillMoney() + "RMB");
}
}
}
public class StoreCoRClient
{
public static void main(String a[])
{
Leader objDirector,objDepartmentManager,objViceManager,objGeneralManager;
objDirector=new Director("Jack");
objDepartmentManager=new DepartmentManager("刘德华");
objViceManager=new ViceManager("张曼玉");
objGeneralManager=new GeneralManager("成龙");
objDirector.setSuccessor(objDepartmentManager);
objDepartmentManager.setSuccessor(objViceManager);
objViceManager.setSuccessor(objGeneralManager);
ShoppingRequest shopping1=new ShoppingRequest("购买打印纸",1000.00);
System.out.println("----------------------------------------");
objDirector.handleRequest(shopping1);
ShoppingRequest shopping2=new ShoppingRequest("办公室配置空调",25000.00);
System.out.println("----------------------------------------");
objDirector.handleRequest(shopping2);
ShoppingRequest shopping3=new ShoppingRequest("更新电脑",80000.00);
System.out.println("----------------------------------------");
objDirector.handleRequest(shopping3);
ShoppingRequest shopping4=new ShoppingRequest("车间维修",150000.00); System.out.println("----------------------------------------");
objDirector.handleRequest(shopping4);
ShoppingRequest shopping5=new ShoppingRequest("收购RL公司",4000000.00);
System.out.println("----------------------------------------");
objDirector.handleRequest(shopping5);
}
}
运行结果:
(5) 命令模式
某软件公司欲开发一个基于Windows平台的公告板系统。系统提供一个主菜单(Menu),在主菜单中包含了一些菜单项(MenuItem),可以通过Menu类的addMenuItem()方法增加菜单项。菜单项的主要方法是click(),每一个菜单项包含一个抽象命令类,具体命令类包括OpenCommand(打开命令),CreateCommand(新建命令),EditCommand(编辑命令)等,命令类具有一个execute()方法,用于调用公告板系统界面类(BoardScreen)的open()、create()、edit()等方法。现使用命令模式设计该系统,使得MenuItem类与BoardScreen类的耦合度降低,绘制类图并编程实现。
package CommandPattern;
import java.util.ArrayList;
//菜单栏
class Menu
{
private ArrayList<MenuItem> menuItemList=new ArrayList<CommandPattern.MenuItem>();
public void addMenuItem(MenuItem item){
this.menuItemList.add(item);
}
public MenuItem getMenuItemByName(String itemName){
for(int i=0; i<menuItemList.size();i++){
if(menuItemList.get(i).getItemName().equals(itemName)){
return menuItemList.get(i);
}
}
return null;
}
}
//请求发送者
class MenuItem
{
private Command command;
private String itemName;
MenuItem(String name,Command cmd)
{
this.itemName=name;
mand=cmd;
}
public Command getCommand() {
return command;
}
public void setCommand(Command command) {
mand = command;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public void click()
{
System.out.println("MenuItem "+this.itemName+" clicked!");
mand.execute();
}
}
//抽象命令
interface Command
{
void execute();
}
//请求接收者
class BoardScreen
{
public void open()
{
System.out.println("BoardScreen opened!");
}
public void create()
{
System.out.println("BoardScreen created!");
}
public void edit()
{
System.out.println("BoardScreen editing!");
}
}
//具体命令
class OpenCommand implements Command
{
private BoardScreen myBoardScreen;
public OpenCommand(BoardScreen myBoardScreen)
{
this.myBoardScreen=myBoardScreen;
}
public void execute()
{
myBoardScreen.open();
}
}
//具体命令
class CreateCommand implements Command
{
private BoardScreen myBoardScreen;
public CreateCommand(BoardScreen myBoardScreen)
{
this.myBoardScreen=myBoardScreen;
}
public void execute()
{
myBoardScreen.create();
}
}
//具体命令
class EditCommand implements Command
{
private BoardScreen myBoardScreen;
public EditCommand(BoardScreen myBoardScreen)
{
this.myBoardScreen=myBoardScreen;
}
public void execute()
{
myBoardScreen.edit();
}
}
//客户端
public class MenueCommandClient {
public static void main(String a[])
{
BoardScreen screen=new BoardScreen();
Menu menu=new Menu();
MenuItem itemOpen=new MenuItem("open",new OpenCommand(screen));
MenuItem itemCreate=new MenuItem("create",new CreateCommand(screen));
MenuItem itemEdit=new MenuItem("edit",new EditCommand(screen));
menu.addMenuItem(itemOpen);
menu.addMenuItem(itemCreate);
menu.addMenuItem(itemEdit);
menu.getMenuItemByName("open").click();
System.out.println("-------------------------------------");
menu.getMenuItemByName("create").click();
System.out.println("-------------------------------------");
menu.getMenuItemByName("edit").click();
}
}
运行结果:
(6) 迭代器模式
某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商品名称数组的双向(前向和后向)遍历。绘制类图并编程实现(设计方案必须符合DIP)。
package IteratorPattern;
interface MyCollection
{
MyIterator createIterator();
}
//双向迭代器
interface MyIterator
{
void first();
void last();
void next();
void previous();
boolean hasNext();
boolean hasPrevious();
boolean isFirst();
boolean isLast();
Object currentItem();
}
class NewCollection implements MyCollection
{
private Object[] obj={"N","o","K","i","a"};
//实现接口MyCollection的创建迭代器的方法
public MyIterator createIterator()
{
return new NewIterator();
}
//内部类迭代器
private class NewIterator implements MyIterator
{
private int currentIndex=0;
public void first()
{
currentIndex=0;
}
public void last() {
currentIndex=obj.length-1;
}
public void next()
{
if(currentIndex<obj.length)
{
currentIndex++;
}
}
public void previous()
{
if(currentIndex>0)
{
currentIndex--;
}
}
public boolean hasNext()
{
if(currentIndex<obj.length-1)
{
return true;
}
return false;
}
public boolean hasPrevious()
{
if(currentIndex>0)
{
return true;
}
return false;
}
public boolean isLast()
{
return currentIndex==obj.length-1;
}
public boolean isFirst()
{
return currentIndex==0;
}
public Object currentItem()
{
return obj[currentIndex];
}
}
}
public class MyIteratorClient {
public static void main(String a[])
{
MyCollection collection = new NewCollection();
MyIterator i = collection.createIterator();
System.out.println("正向遍历-------------------------");
i.first(); //调整指针的当前状态在第一个位置
System.out.print(i.currentItem().toString()+" ");
while(i.hasNext())
{ i.next();
System.out.print(i.currentItem().toString()+" ");
}
System.out.println("\n逆向遍历-------------------------");
i.last();//调整指针的当前状态在最后位置
System.out.print(i.currentItem().toString()+" ");
while(i.hasPrevious())
{
i.previous();
System.out.print(i.currentItem().toString()+" ");
}
}
}
运行结果:
(7) 观察者模式
某在线股票软件需要提供如下功能:当股票购买者所购买的某支股票价格变化幅度达到5%时,系统将自动发送通知(包括新价格)给购买该股票的股民。现使用观察者模式设计该系统,绘制类图并编程实现。
package ObserverPattern;
import java.util.*;
//某在线股票软件需要提供如下功能:
//当股票购买者所购买的某支股票价格变化幅度达到5%时,
//系统将自动发送通知(包括新价格)给购买该股票的股民。
//现使用观察者模式设计该系统,绘制类图并编程实现。
interface MyObserver
{
void response();
}
abstract class MySubject
{
private Vector v=new Vector();
public void addObserver(MyObserver observer)
{
this.v.add(observer);
}
public void deleteOb
展开阅读全文