设计模式第三次作业
1. 题目1
要求:某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商品名称数组的双向(向前和向后)遍历。使用Iterator模式来设计。
类图设计如下:
代码如下:
/**
* 抽象聚合类,声明createIterator()方法创建迭代器对象
*/
public abstract class Array {
public abstract Iterator createIterator();
}
/**
* 抽象迭代器类,声明forwardTravel()前向遍历方法
* 和backwardTravel()后向遍历方法
*/
public abstract class Iterator {
public abstract void forwardTravel();
public abstract void backwardTravel();
}
/**
* 具体聚合类,实现createIterator()方法创建具体迭代器对象
*/
public class NameArray extends Array {
private List<String> nameList = new ArrayList<>(Arrays.asList("Apple",
"Banana", "Pear", "Watermelon"));
public List<String> getNameList() {
return nameList;
}
@Override
public Iterator createIterator() {
return new NameIterator(this);
}
}
/**
* 具体迭代器类,实现forwardTravel()前向遍历方法
* 和backwardTravel()后向遍历方法
*/
public class NameIterator extends Iterator {
private NameArray nameArray; // 对具体聚合类的引用
public NameIterator(NameArray nameArray) { // 注入具体聚合类的引用
this.nameArray = nameArray;
}
@Override
public void forwardTravel() {
List<String> nameList = nameArray.getNameList();
// 向前遍历
for (int i = nameList.size() - 1; i >= 0; i--) {
System.out.println(nameList.get(i));
}
}
@Override
public void backwardTravel() {
List<String> nameList = nameArray.getNameList();
// 向后遍历
for (String name : nameList) {
System.out.println(name);
}
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
NameArray nameArray = new NameArray(); // 创建具体聚合类对象
Iterator iterator = nameArray.createIterator(); // 调用具体聚合类对象的createIterator()方法获得具体迭代器对象
iterator.backwardTravel(); // 向后遍历
iterator.forwardTravel(); // 向前遍历
}
}
输出结果:
Apple
Banana
Pear
Watermelon
Watermelon
Pear
Banana
Apple
2. 题目2
要求:某公司欲开发一个基于Windows平台的公告板系统,系统提供主菜单(Menu)其中有菜单项(MenuItem)。通过Menu类的addMenuItem()方法增加菜单项。菜单项的打开方法是click(),每个菜单项包含一个抽象命令类,具体命令类包括OpenCommand()、CreateCommand()、EditCommand()等,命令类具有一个execute()方法,用于调用公告板系统界面类(BoardScreen())的open()、create()、edit())等方法。使用Command模式来设计。
类图设计如下:
代码如下:
/**
* 菜单类,通过addMenuItem()方法添加菜单项
* 通过clickMenuItem()方法点击某个菜单项
*/
public class Menu {
private List<MenuItem> menuItemList = new ArrayList<>();
public void addMenuItem(MenuItem menuItem) {
menuItemList.add(menuItem);
}
public void clickMenuItem(int index) {
menuItemList.get(index).click();
}
}
/**
* 菜单项类,包含一个抽象命令对象
* click()方法调用命令对象的execute()方法
*/
public class MenuItem {
private Command command;
public MenuItem(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void click() {
command.execute();
}
}
/**
* 抽象命令类,声明execute()方法
*/
public abstract class Command {
public abstract void execute();
}
/**
* 具体命令类,execute()调用boardScreen的open()方法
*/
public class OpenCommand extends Command {
private BoardScreen boardScreen;
public OpenCommand(BoardScreen boardScreen) {
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.open();
}
}
/**
* 具体命令类,execute()调用boardScreen的create()方法
*/
public class CreateCommand extends Command {
private BoardScreen boardScreen;
public CreateCommand(BoardScreen boardScreen) {
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.create();
}
}
/**
* 具体命令类,execute()调用boardScreen的edit()方法
*/
public class EditCommand extends Command {
private BoardScreen boardScreen;
public EditCommand(BoardScreen boardScreen) {
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.edit();
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
BoardScreen boardScreen = new BoardScreen(); // 创建公告板系统界面
Menu menu = new Menu(); // 创建菜单
OpenCommand openCommand = new OpenCommand(boardScreen); // 创建OpenCommand对象
MenuItem openItem = new MenuItem(openCommand); // 创建open菜单项并注入命令对象
menu.addMenuItem(openItem); // 菜单项添加到菜单中
CreateCommand createCommand = new CreateCommand(boardScreen); // 创建CreateCommand对象
MenuItem createItem = new MenuItem(createCommand); // 创建create菜单项并注入命令对象
menu.addMenuItem(createItem); // 菜单项添加到菜单中
EditCommand editCommand = new EditCommand(boardScreen); // 创建EditCommand对象
MenuItem editItem = new MenuItem(editCommand); // 创建edit菜单项并注入命令对象
menu.addMenuItem(editItem); // 菜单项添加到菜单中
menu.clickMenuItem(0); // 点击open菜单项
menu.clickMenuItem(1); // 点击create菜单项
menu.clickMenuItem(2); // 点击edit菜单项
}
}
输出结果:
open board
create board
edit board
3. 题目3
要求:某论坛系统欲增加一个虚拟聊天室,允许论坛会员通过该聊天室进行信息交流,普通会员(CommonMember)可以给其他会员发送文本信息,钻石会员(DiamondMember)可以给其他会员发送文本和图片信息。该聊天室可以对不雅字符进行过滤,如“TMD”等字符,还可以对发送图片大小进行控制。使用Mediator模式来设计。
类图设计如下:
代码如下:
/**
* 会员抽象类,包含对ChatRoom中介类的引用
*/
public abstract class Member {
protected ChatRoom chatRoom;
protected String name;
public Member(String name) {
this.chatRoom = chatRoom;
this.name = name;
}
public void setChatRoom(ChatRoom chatRoom) {
this.chatRoom = chatRoom;
}
public void sendText(String text) {
System.out.println("Member " + name + " Send Text:" + text);
chatRoom.sendText(name, text); // 通知中介者
}
public void recvText(String text) {
System.out.println("Member " + name + " Receive Text:" + text);
}
public void recvPic(String pic) {
System.out.println("Member " + name + " Receive Picture:" + pic);
}
public String getName() {
return name;
}
}
/**
* 普通会员类
*/
public class CommonMember extends Member {
public CommonMember(String name) {
super(name);
}
}
/**
* 钻石会员类,添加sendPic()发送图片方法
*/
public class DiamondMember extends Member {
public DiamondMember(String name) {
super(name);
}
public void sendPic(String pic) {
System.out.println("Member " + name + " Send Picture:" + pic);
chatRoom.sendPic(name, pic); // 通知中介者
}
}
/**
* 聊天室中介者抽象类,声明sendText()发送文本方法
* 和sendPic()发送图片方法
*/
public abstract class ChatRoom {
protected List<Member> memberList = new ArrayList<>();
public void regMember(Member member) {
memberList.add(member);
}
public abstract void sendText(String from, String text);
public abstract void sendPic(String from, String pic);
}
/**
* 聊天室中介者具体类,实现sendText()发送文本方法
* 和sendPic()发送图片方法,同时包含文本过滤器和图片大小控制器的引用
*/
public class ConcreteRoom extends ChatRoom {
private TextFilter textFilter;
private PicController picController;
public ConcreteRoom(TextFilter textFilter, PicController picController) {
this.textFilter = textFilter;
this.picController = picController;
}
@Override
public void sendText(String from, String text) {
String filterText = textFilter.filter(text);
for (Member member : memberList) {
if (!member.getName().equals(from)) {
member.recvText(filterText);
}
}
}
@Override
public void sendPic(String from, String pic) {
boolean flag = picController.canSend(pic);
if (flag) {
for (Member member : memberList) {
if (!member.getName().equals(from)) {
member.recvPic(pic);
}
}
}
else {
for (Member member : memberList) {
if (member.getName().equals(from)) {
member.recvText("系统信息:图片大小超过限制,发送失败");
}
}
}
}
public void setTextFilter(TextFilter textFilter) {
this.textFilter = textFilter;
}
public void setPicController(PicController picController) {
this.picController = picController;
}
}
/**
* 文本过滤器抽象类,声明filter()过滤文本方法
*/
public abstract class TextFilter {
public abstract String filter(String text);
}
/**
* 文本过滤器具体类,实现filter()过滤文本方法
*/
public class NormalTextFilter extends TextFilter {
@Override
public String filter(String text) {
String resText = text;
resText = resText.replaceAll("[Tt][Mm][Dd]", "***");
return resText;
}
}
/**
* 图片大小控制器抽象类,声明canSend()检测是否可发送方法
*/
public abstract class PicController {
public abstract boolean canSend(String pic);
}
/**
* 图片大小控制器具体类,实现canSend()检测是否可发送方法
*/
public class NormalPicController extends PicController {
@Override
public boolean canSend(String pic) {
return outOfLimitedSize(pic) == false;
}
private boolean outOfLimitedSize(String pic) {
return pic.length() > 10;
}
}
用户调用如下:
public class Client {
public static void main(String[] args) {
TextFilter textFilter = new NormalTextFilter(); // 创建文本过滤器对象
PicController picController = new NormalPicController(); // 创建图片大小控制器对象
ConcreteRoom room = new ConcreteRoom(textFilter, picController); // 创建聊天室
CommonMember commonMember1 = new CommonMember("张三"); // 创建普通会员张三
room.regMember(commonMember1); // 聊天室注册张三
commonMember1.setChatRoom(room); // 会员聊天室信息更新
CommonMember commonMember2 = new CommonMember("李四"); // 创建普通会员李四
room.regMember(commonMember2); // 聊天室注册李四
commonMember2.setChatRoom(room); // 会员聊天室信息更新
DiamondMember diamondMember1 = new DiamondMember("王老五"); // 创建钻石会员王老五
room.regMember(diamondMember1); // 聊天室注册王老五
diamondMember1.setChatRoom(room); // 会员聊天室信息更新
commonMember1.sendText("大家好"); // 张三发了一条“大家好”的文本信息
commonMember2.sendText("张三TMD"); // 李四发了一条“张三TMD”的文本信息(TMD会被过滤)
diamondMember1.sendText("文明你我他"); // 王老五发了一条“文明你我他”的文本信息
diamondMember1.sendPic("PictureA"); // 王老五发了一张小图片(在大小限制范围内)
diamondMember1.sendPic("LongLongPictureB"); // 王老五发了一张大图片(超过大小限制,发送失败)
}
}
输出结果:
Member 张三 Send Text:大家好
Member 李四 Receive Text:大家好
Member 王老五 Receive Text:大家好
Member 李四 Send Text:张三TMD
Member 张三 Receive Text:张三***
Member 王老五 Receive Text:张三***
Member 王老五 Send Text:文明你我他
Member 张三 Receive Text:文明你我他
Member 李四 Receive Text:文明你我他
Member 王老五 Send Picture:PictureA
Member 张三 Receive Picture:PictureA
Member 李四 Receive Picture:PictureA
Member 王老五 Send Picture:LongLongPictureB
Member 王老五 Receive Text:系统信息:图片大小超过限制,发送失败
4. 题目4
要求:设计一个网上书店,对系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,语言类图书(LanguageBook)每本都有2元的折扣,小说类图书(NovelBook)每100元有15元的折扣。使用Strategy模式来设计。
类图设计如下:
代码如下:
/**
* 书籍类,包含价格策略的引用
*/
public class Book {
private PricePolicy pricePolicy;
public void setPricePolicy(PricePolicy pricePolicy) {
this.pricePolicy = pricePolicy;
}
public double getCost(double pay) {
return pricePolicy.calcPrice(pay);
}
}
/**
* 价格策略抽象类,声明calcPrice()计算价格的方法
*/
public abstract class PricePolicy {
public abstract double calcPrice(double pay);
}
/**
* 价格策略具体类,实现calcPrice()计算价格的方法,按折扣比率算
*/
public class RatePolicy extends PricePolicy {
private double rate;
public RatePolicy() {
rate = 0.1;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public double calcPrice(double pay) {
return pay * (1 - rate);
}
}
/**
* 价格策略具体类,实现calcPrice()计算价格的方法,按直接减折扣算
*/
public class DiscountPolicy extends PricePolicy {
private double discount;
public DiscountPolicy() {
discount = 2;
}
public void setDiscount(double discount) {
this.discount = discount;
}
@Override
public double calcPrice(double pay) {
return pay - discount;
}
}
/**
* 价格策略具体类,实现calcPrice()计算价格的方法,按满减折扣算
*/
public class FullDiscountPolicy extends PricePolicy {
private double fullBound;
private double discount;
public FullDiscountPolicy() {
fullBound = 100;
discount = 15;
}
public void setFullBound(double fullBound) {
this.fullBound = fullBound;
}
public void setDiscount(double discount) {
this.discount = discount;
}
@Override
public double calcPrice(double pay) {
if (pay >= fullBound) {
return pay - discount;
} else {
return pay;
}
}
}
用户调用如下:
public class Client {
public static void main(String args[]) {
PricePolicy ratePolicy = new RatePolicy(); // 创建折扣比率的价格策略对象
PricePolicy discountPolicy = new DiscountPolicy(); // 创建直接减折扣的价格策略对象
PricePolicy fullDiscountPolicy = new FullDiscountPolicy(); // 创建满减折扣的价格策略对象
Book book = new Book();
book.setPricePolicy(ratePolicy); // 注入价格策略
double cost = book.getCost(100);
System.out.println("cost = " + cost);
book.setPricePolicy(discountPolicy); // 注入价格策略
cost = book.getCost(100);
System.out.println("cost = " + cost);
book.setPricePolicy(fullDiscountPolicy); // 注入价格策略
cost = book.getCost(100);
System.out.println("cost = " + cost);
}
}
输出结果:
cost = 90.0
cost = 98.0
cost = 85.0