设计模式第三次作业
设计模式第三次作业
1、要求:某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商品名称数组的双向(向前和向后)遍历。使用Iterator模式来设计。
类图如下:
看不清请点这里
代码:
interface Iterator{
public void begin();//将迭代器的游标置为-1 便于使用next进行正向遍历
public void Cbegin();//从末尾开始的游标 便于以后使用next进行逆向遍历
public String FirstElement();//返回正向首个元素
public String EndElement();//返回正向末尾元素
public String CFirstElement();//返回逆向首个元素
public String CEndElement();//返回逆向末尾元素
public boolean hasnext();//判断是否还可继续遍历
public String next();//取出下一个元素
public String pre();//取出上一个元素
public String current();//取出当前元素
}
class MyIterator implements Iterator{
private List<String> list;
private StringArray stringArray;
private int i=0;
private int direction=1;//定义方向1为正向 0为反向
private String warning="当前商品名称数组为空,非法取值!";
public MyIterator(StringArray stringArray) {
this.stringArray=stringArray;
this.list=this.stringArray.getList();
}
public String FirstElement() {
// TODO Auto-generated method stub
if(list.size()==0){
return warning;
}else {
direction=1;
i=0;
return list.get(i);
}
}
public String EndElement() {
// TODO Auto-generated method stub
if(list.size()==0){
return warning;
}else{
direction=1;
i=list.size()-1;
return list.get(i);
}
}
public String CFirstElement() {
// TODO Auto-generated method stub
if(list.size()==0){
return warning;
}else {
direction=0;
i=list.size()-1;
return list.get(i);
}
}
public String CEndElement() {
// TODO Auto-generated method stub
if(list.size()==0){
return warning;
}else {
direction=0;
i=0;
return list.get(i);
}
}
public boolean hasnext() {
// TODO Auto-generated method stub
if(direction==1){
//正向遍历
if(i==list.size()-1){
return false;
}
return true;
}else if (direction==0) {
//反向遍历
if(i==0){
return false;
}
return true;
}
return true;
}
public String next() {
// TODO Auto-generated method stub
if(direction==1){
//正向遍历
return list.get(++i);
}else if(direction==0){
return list.get(--i);
}
return null;
}
public String pre() {
// TODO Auto-generated method stub
if(direction==1){
//正向遍历
return list.get(--i);
}else if(direction==0){
return list.get(++i);
}
return null;
}
public void begin() {
// TODO Auto-generated method stub
i=-1;
}
public String current() {
// TODO Auto-generated method stub
return list.get(i);
}
public void Cbegin() {
// TODO Auto-generated method stub
i=list.size();
}
}
interface IntefaceStringArray{
public void add(String item);
public void remove(String Item);
public Iterator iterator();
public int size();
public List<String> getList();
}
class StringArray implements IntefaceStringArray{
private List<String> list;
public StringArray() {
list =new ArrayList<String>();
}
public void add(String item) {
// TODO Auto-generated method stub
list.add(item);
}
public void remove(String item) {
// TODO Auto-generated method stub
list.remove(item);
}
public Iterator iterator() {
// TODO Auto-generated method stub
return new MyIterator(this);
}
public int size() {
// TODO Auto-generated method stub
return list.size();
}
public List<String> getList() {
// TODO Auto-generated method stub
return list;
}
}
//测试代码
IntefaceStringArray ISA=new StringArray();
ISA.add("tom");
ISA.add("jerry");
ISA.add("sam");
ISA.add("ccc");
ISA.add("bbb");
Iterator iterator = ISA.iterator();
System.out.println("正向遍历");
System.out.println("FirstProductName is "+iterator.FirstElement());
System.out.println(iterator.current()+"'s Next is "+iterator.next());
System.out.println(iterator.current()+"'s Pre is "+iterator.pre());
System.out.println("EndProductName is "+iterator.EndElement());
System.out.println("正向轮询");
iterator.begin();//在轮询前 先将迭代器置为first 和现成的语法是符合的
while(iterator.hasnext()){
System.out.println(iterator.next());
}
System.out.println("反向遍历");
System.out.println("FirstProductName is "+iterator.CFirstElement());
System.out.println(iterator.current()+"'s Next is "+iterator.next());
System.out.println(iterator.current()+"'s Pre is "+iterator.pre());
System.out.println("EndProductName is "+iterator.CEndElement());
System.out.println("反向轮询");
iterator.Cbegin();//在轮询前 先将迭代器置为first 和现成的语法是符合的
while(iterator.hasnext()){
System.out.println(iterator.next());
}
//运行结果
正向遍历
FirstProductName is tom
tom's Next is jerry
jerry's Pre is tom
EndProductName is bbb
正向轮询
tom
jerry
sam
ccc
bbb
反向遍历
FirstProductName is bbb
bbb's Next is ccc
ccc's Pre is bbb
EndProductName is tom
反向轮询
bbb
ccc
sam
jerry
tom
小结
- 迭代器模式:这里的迭代器模式,就是模拟类似c++里面的vector等容器的迭代器的方法,通过迭代器来对于整个容器进行遍历。同样的,这里是对StringArray进行遍历,在实现中的要点是在于在StringArray类中写入list记录,并在创建迭代器对象的时候将已经存好信息的list传过去。之后,在list中遍历。
2、要求:某公司欲开发一个基于Windows平台的公告板系统,系统提供主菜单(Menu)其中有菜单项(MenuItem)。通过Menu类的addMenuItem()方法增加菜单项。菜单项的打开方法是click(),每个菜单项包含一个抽象命令类,具体命令类包括OpenCommand()、CreateCommand()、EditCommand()等,命令类具有一个execute()方法,用于调用公告板系统界面类(BoardScreen())的open()、create()、edit())等方法。使用Command模式来设计。
类图如下:
代码:
class Menu{
List<MenuItem> list;//记录所有的menuItem
public Menu() {
list=new ArrayList<MenuItem>();
}
public void addMenuItem(MenuItem item){
list.add(item);
}
public MenuItem get(int i){
return list.get(i);
}
}
class MenuItem{
private String name;//menuItem的名称
private String shortcutKey;//menuItem的快捷键
private Command command;
public MenuItem(String name,String shortcString) {
this.name=name;
this.shortcutKey=shortcString;
}
public void setCommand(Command command){
this.command=command;
}
public void click(){//设置点击信号
command.excute();
}
}
abstract class Command{
public abstract void excute();
}
class OpenCommand extends Command{
BoardScreen screen;
public OpenCommand() {
screen=new BoardScreen();
}
@Override
public void excute() {
// TODO Auto-generated method stub
screen.open();
}
}
class CreateCommand extends Command{
BoardScreen screen;
public CreateCommand() {
screen=new BoardScreen();
}
@Override
public void excute() {
// TODO Auto-generated method stub
screen.create();
}
}
class EditCommand extends Command{
BoardScreen screen;
public EditCommand() {
screen=new BoardScreen();
}
@Override
public void excute() {
// TODO Auto-generated method stub
screen.edit();
}
}
class BoardScreen{
public void open(){
System.out.println("在界面执行打开文件操作");
}
public void create(){
System.out.println("在界面执行新建文件操作");
}
public void edit(){
System.out.println("在界面执行编辑文件操作");
}
}
//测试代码
Menu menu=new Menu();
menu.addMenuItem(new MenuItem("CreatFileMenuItem", "Ctrl+N"));
menu.addMenuItem(new MenuItem("OpenFileMenuItem", "Ctrl+O"));
menu.addMenuItem(new MenuItem("EditFileMenuItem","Ctrl+1"));
menu.get(0).setCommand(new CreateCommand());
menu.get(1).setCommand(new OpenCommand());
menu.get(2).setCommand(new EditCommand());
menu.get(0).click();
menu.get(1).click();
menu.get(2).click();
//运行结果
在界面执行新建文件操作
在界面执行打开文件操作
在界面执行编辑文件操作
小结
- 命令模式:它要求命令的发出者与命令的执行者并不是一个。在这里,MenuItem可作为命令的发出者,而真正的执行是在BoardScreen中执行操作。这里就类似Qt开发中添加MenuBar的方法。先得到一个menu对象,之后,在得到若干个MenuItem对象,对于每个MenuItem对象指定他们的名称、快捷键等信息,再指定他们发出click()的信号时连接的哪个槽函数,再槽函数中执行对应的操作。在本次代码中,类似的,每个MenuItem的click()信号发出时,也就是调用click()方法时,调用command中的excute()方法,也就是可以理解为上面的槽函数,最终去调用BoardScreen的对应方法。
3、要求:某论坛系统欲增加一个虚拟聊天室,允许论坛会员通过该聊天室进行信息交流,普通会员(CommonMember)可以给其他会员发送文本信息,钻石会员(DiamondMember)可以给其他会员发送文本和图片信息。该聊天室可以对不雅字符进行过滤,如“TMD”等字符,还可以对发送图片大小进行控制。使用Mediator模式来设计。
类图如下:
代码:
abstract class Member{
public AbsMediator mediator;
public String userName;
public abstract void sendMessage(String message);
public abstract void sendPicture(String message);
public abstract void setMediator(AbsMediator mediator);
}
class CommonMember extends Member{
public CommonMember(String userName) {
super();
this.userName=userName;
}
@Override
public void sendMessage(String message) {
// TODO Auto-generated method stub
mediator.sendMessage(userName, message,this);
}
@Override
public void sendPicture(String message) {
// TODO Auto-generated method stub
mediator.sendMessage(" @"+userName+" 系统提示", "对不起,您的会员等级不可发送图片消息!请升级钻石会员发送!",this);
}
@Override
public void setMediator(AbsMediator mediator) {
// TODO Auto-generated method stub
this.mediator=mediator;
}
}
class DiamondMember extends Member{
public DiamondMember(String userName) {
super();
// TODO Auto-generated constructor stub
this.userName=userName;
}
@Override
public void sendMessage(String message) {
// TODO Auto-generated method stub
mediator.sendMessage(userName, message,this);
}
@Override
public void sendPicture(String message) {
// TODO Auto-generated method stub
mediator.sendMessage(userName, message+"发送成功",this);
}
@Override
public void setMediator(AbsMediator mediator) {
// TODO Auto-generated method stub
this.mediator=mediator;
}
}
abstract class AbsMediator{
public abstract void sendMessage(String userName,String message,Member member);
}
class Mediator extends AbsMediator{
private CommonMember common;
private DiamondMember diamond;
public Mediator(CommonMember common,DiamondMember diamond) {
this.common=common;
this.diamond=diamond;
}
public void sendMessage(String userName,String message,Member member){
if(message.contains("TMD")){
message=message.replaceAll("TMD", "***");
}
if(common==member){
System.out.println("普通会员"+userName+": "+message);
}else {
System.out.println("钻石会员"+userName+": "+message);
}
}
}
//测试代码
CommonMember common=new CommonMember("张三");
DiamondMember diamond=new DiamondMember("王五");
AbsMediator mediator=new Mediator(common,diamond);
common.setMediator(mediator);
diamond.setMediator(mediator);
common.sendMessage("hahah");
diamond.sendMessage("哈哈哈");
common.sendPicture("22.png");
diamond.sendPicture("33.png");
common.sendMessage("TMD,不是会员还不让发图片!");
diamond.sendMessage("哈哈哈,张三发敏感词,被查到了!");
//运行结果
普通会员张三: hahah
钻石会员王五: 哈哈哈
普通会员 @张三 系统提示: 对不起,您的会员等级不可发送图片消息!请升级钻石会员发送!
钻石会员王五: 33.png发送成功
普通会员张三: ***,不是会员还不让发图片!
钻石会员王五: 哈哈哈,张三发敏感词,被查到了!
小结
- 中介模式:这个模式其实就在于中介维护了两个对象,在使用的时候设置进去就可以,对于两种会员的对象来说,他们也需要知道中介是谁。他们通过中介来进行通讯。这里就是普通会员与钻石会员,他们都是通过将消息发到公共聊天室这一中介进行通讯,但是这两种会员对应的对象可以不在空间上相近。在实现上就是各种会员中都维护中介对象,会员发送消息,由中介者来完成。
- 其实更为明显的例子可以为出租房子的人(房主)和寻找租房的人之间通过中介来联系。中介需要知道租房的和房主是谁,寻找租房的人找到中介,跟中介提要求等,中介再反馈到房主。房主的回话再通过中介传达给租房者。在本题中其实是省略了中介反馈以及中介传达的过程,这两个过程由两种会员的对象通过看聊天室实现。
4、要求:设计一个网上书店,对系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,语言类图书(LanguageBook)每本都有2元的折扣,小说类图书(NovelBook)每100元有15元的折扣。使用Strategy模式来设计。
类图如下:
看不清请点这里
代码:
abstract class Strategy {
public abstract double getActualCost(double cost);
}
class PersentStrategy extends Strategy{
double persent;//打折多少
public PersentStrategy(int persent) {
super();
this.persent=persent;
}
@Override
public double getActualCost(double cost) {
// TODO Auto-generated method stub
return cost-cost*persent/100;
}
}
class SubStrategy extends Strategy{
private int sub;//立减多少
public SubStrategy(int sub) {
super();
this.sub=sub;
}
@Override
public double getActualCost(double cost) {
// TODO Auto-generated method stub
return cost-sub;
}
public void setDiscountStrategy() {
// TODO Auto-generated method stub
}
}
class subForEachStrategy extends Strategy{
private int Each;//每满多少
private int sub;//减多少
public subForEachStrategy(int Each,int sub) {
super();
this.Each=Each;
this.sub=sub;
}
@Override
public double getActualCost(double cost) {
// TODO Auto-generated method stub
return cost-(cost/Each)*sub;
}
public void setDiscountStrategy() {
// TODO Auto-generated method stub
}
}
abstract class Book{
public Strategy strategy;
public abstract void setStrategy(Strategy strategy);
}
class ComputerBook extends Book{
private String name;
private double cost;
@Override
public void setStrategy(Strategy strategy) {
// TODO Auto-generated method stub
this.strategy=strategy;
}
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
public void setCost(double cost) {
// TODO Auto-generated method stub
this.cost=cost;
}
public double getActualCost() {
// TODO Auto-generated method stub
return strategy.getActualCost(cost);
}
public String getName() {
// TODO Auto-generated method stub
return name;
}
public double getCost() {
// TODO Auto-generated method stub
return cost;
}
}
class LanguageBook extends Book{
private String name;
private double cost;
@Override
public void setStrategy(Strategy strategy) {
// TODO Auto-generated method stub
this.strategy=strategy;
}
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
public void setCost(double cost) {
// TODO Auto-generated method stub
this.cost=cost;
}
public double getActualCost() {
// TODO Auto-generated method stub
return strategy.getActualCost(cost);
}
public String getName() {
// TODO Auto-generated method stub
return name;
}
public double getCost() {
// TODO Auto-generated method stub
return cost;
}
}
class NovelBook extends Book{
private String name;
private double cost;
@Override
public void setStrategy(Strategy strategy) {
// TODO Auto-generated method stub
this.strategy=strategy;
}
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
public void setCost(double cost) {
// TODO Auto-generated method stub
this.cost=cost;
}
public double getActualCost() {
// TODO Auto-generated method stub
return strategy.getActualCost(cost);
}
public String getName() {
// TODO Auto-generated method stub
return name;
}
public double getCost() {
// TODO Auto-generated method stub
return cost;
}
}
//测试代码
Strategy strategy;
System.out.println("购物清单:");
System.out.println("品名 原价 折后价格");
strategy=new PersentStrategy(10);
ComputerBook cb=new ComputerBook();
cb.setName("ComputerBook");
cb.setCost(10);
cb.setStrategy(strategy);
System.out.println(cb.getName()+" "+cb.getCost()+" "+cb.getActualCost());
strategy=new SubStrategy(2);
LanguageBook lb=new LanguageBook();
lb.setName("LanguageBook");
lb.setCost(20);
lb.setStrategy(strategy);
System.out.println(lb.getName()+" "+lb.getCost()+" "+lb.getActualCost());
strategy=new subForEachStrategy(100,15);
NovelBook nb=new NovelBook();
nb.setName("NovelBook");
nb.setCost(200);
nb.setStrategy(strategy);
System.out.println(nb.getName()+" "+nb.getCost()+" "+nb.getActualCost());
//运行结果
小结
- 策略模式:就是对应不同的对象选取不同的策略。这里开放了设定的数据,方便以后进行修改打折比例、立减多少,满多少减多少等的数据。