设计模式第三次作业

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

posted on 2017-11-23 19:09  蔡鸟一斤  阅读(944)  评论(1编辑  收藏  举报

导航