设计模式第三次作业

github地址

1、要求:某商品管理系统的商品名称存储在一个字符串数组中,现需要自定义一个双向迭代器(MyIterator)实现对该商品名称数组的双向(向前和向后)遍历。使用Iterator模式来设计。

github地址

类图:

迭代器

源码:

public interface MyIterator {
    boolean prev();
    boolean next();
    String curItem();
}
public interface ProductList {
    MyIterator getIterator();
}
public class MyProductList implements ProductList{
    private String[] products;

    public MyProductList(String[] products) {
        this.products = products;
    }

    @Override
    public MyIterator getIterator() {
        return new MyProductListIterator();
    }

    private class MyProductListIterator implements MyIterator{
        private int curIndex = 0;

        @Override
        public boolean prev() {
            boolean hasPrev = curIndex > 0;
            if(hasPrev){
                --curIndex;
            }
            return hasPrev;
        }

        @Override
        public boolean next() {
            boolean hasNext = curIndex < products.length -1;
            if(hasNext){
                ++curIndex;
            }
            return hasNext;
        }

        @Override
        public String curItem() {
            return products[curIndex];
        }
    }

}

2、某公司欲开发一个基于Windows平台的公告板系统,系统提供主菜单(Menu)其中有菜单项(MenuItem)。通过Menu类的addMenuItem()方法增加菜单项。菜单项的打开方法是click(),每个菜单项包含一个抽象命令类,具体命令类包括OpenCommand()、CreateCommand()、EditCommand()等,命令类具有一个execute()方法,用于调用公告板系统界面类(BoardScreen())的open()、create()、edit())等方法。使用Command模式来设计。

github地址

类图:

公告板

源码:

public class BoardScreen {
    private Menu menu;

    public BoardScreen(Menu menu) {
        this.menu = menu;
    }

    public Menu getMenu() {
        return menu;
    }

    public void open(){
        System.out.println("BoardScreen open");
    }
    public void create(){
        System.out.println("BoardScreen create");
    }
    public void edit(){
        System.out.println("BoardScreen edit");
    }
}
public class Menu {
    private List<MenuItem> menuItemList = new ArrayList();

    public void addMenuItem(MenuItem menuItem){
        menuItemList.add(menuItem);
    }

    public void clickAllItems(){
        for (MenuItem menuItem :menuItemList) {
            menuItem.click();
        }
    }
}
public class MenuItem {
    private String name;
    private Command command;

    public MenuItem(String name, Command command){
        this.name = name;
        this.command = command;
    }

    public void click(){
        System.out.print("click the menuItem["+name+"]"+" and ");
        command.execute();
    }
}
public interface Command {
    void execute();
}
public class OpenCommand implements Command {
    private BoardScreen boardScreen;

    public OpenCommand(BoardScreen boardScreen) {
        this.boardScreen = boardScreen;
    }

    @Override
    public void execute() {
        boardScreen.open();
    }
}
public class EditCommand implements Command {
    private BoardScreen boardScreen;

    public EditCommand(BoardScreen boardScreen) {
        this.boardScreen = boardScreen;
    }

    @Override
    public void execute() {
        boardScreen.edit();
    }
}
public class CreateCommand implements Command {
    private BoardScreen boardScreen;

    public CreateCommand(BoardScreen boardScreen) {
        this.boardScreen = boardScreen;
    }

    @Override
    public void execute() {
        boardScreen.create();
    }
}
public class BoardScreenTest {
    private BoardScreen boardScreen;

    @Before
    public void init(){
        boardScreen = new BoardScreen(new Menu());
        boardScreen.getMenu().addMenuItem(new MenuItem("openMenuItem", new OpenCommand(boardScreen)));
        boardScreen.getMenu().addMenuItem(new MenuItem("createMenuItem", new CreateCommand(boardScreen)));
        boardScreen.getMenu().addMenuItem(new MenuItem("editMenuItem", new EditCommand(boardScreen)));
    }

    @Test
    public void test(){
        boardScreen.getMenu().clickAllItems();
    }
}

3、某论坛系统欲增加一个虚拟聊天室,允许论坛会员通过该聊天室进行信息交流,普通会员(CommonMember)可以给其他会员发送文本信息,钻石会员(DiamondMember)可以给其他会员发送文本和图片信息。该聊天室可以对不雅字符进行过滤,如“TMD”等字符,还可以对发送图片大小进行控制。使用Mediator模式来设计。

github地址

类图:

聊天室

源码:

public abstract class Member {
    private String name;
    private AbstractChatRoom chatRoom;

    public Member(String name) {
        this.name = name;
    }

    public void setChatRoom(AbstractChatRoom chatRoom) {
        this.chatRoom = chatRoom;
    }

    public String getName() {
        return name;
    }

    public void sendText(Member to, String text){
        chatRoom.sendText(this, to, text);
    }

    public void sendImage(Member to, String image){
        chatRoom.sendImage(this, to, image);
    }
}
public class CommonMember extends Member{
    public CommonMember(String name) {
        super(name);
    }

    @Override
    public void sendImage(Member to, String image) {
        System.out.println("you need to upgrade to diamond member");
    }
}
public class DiamondMember extends Member {
    public DiamondMember(String name) {
        super(name);
    }
}
public class AbstractChatRoom {
    public void register(Member member){
        member.setChatRoom(this);
    }

    public void sendText(Member from, Member to, String text){
        System.out.println(from.getName() +" to " + to.getName() +" : text("+text+")");
    }
    public void sendImage(Member from, Member to, String image){
        System.out.println(from.getName() +" to " + to.getName() +" : image("+image+")");
    }
}
public class ChatRoom extends AbstractChatRoom{
    @Override
    public void sendText(Member from, Member to, String text) {
        super.sendText(from, to, filterText(text));
    }

    @Override
    public void sendImage(Member from, Member to, String image) {
        if(imageCheck(image)){
            super.sendImage(from, to, image);
        }
    }

    protected String filterText(String text){
        return text.replace("TMD", "***");
    }

    protected boolean imageCheck(String image){
        return image.length() < 4;
    }
}

public class ChatRoomTest {
    private Member a;
    private Member b;

    @Before
    public void inti(){
        a = new CommonMember("commonMember");
        b = new DiamondMember("diamondMember");
        AbstractChatRoom chatRoom = new ChatRoom();
        chatRoom.register(a);
        chatRoom.register(b);
    }

    @Test
    public void test(){
        a.sendText(b, "TMD! b");
        a.sendImage(b, "i1");
        b.sendText(a, "TMD! a");
        b.sendImage(a, "i1sdfasdf");
        b.sendImage(a, "i1");
    }
}

4、要求:设计一个网上书店,对系统中所有的计算机类图书(ComputerBook)每本都有10%的折扣,语言类图书(LanguageBook)每本都有2元的折扣,小说类图书(NovelBook)每100元有15元的折扣。使用Strategy模式来设计。

github地址

类图:

网上书店

源码:

public interface DiscountStrategy {
    public double discount(double price);
}
public class ComputerBookDiscount implements DiscountStrategy{
    @Override
    public double discount(double price) {
        return 0.9*price;
    }
}
public class LanguageBookDiscount implements DiscountStrategy{
    @Override
    public double discount(double price) {
        return price-2;
    }
}
public class NovelBookDiscount implements DiscountStrategy{
    @Override
    public double discount(double price) {
        return price-price/100*15;
    }
}
public class BookShop {
    private ComputerBookDiscount computerBookDiscount;
    private LanguageBookDiscount languageBookDiscount;
    private NovelBookDiscount novelBookDiscount;

    public void setComputerBookDiscount(ComputerBookDiscount computerBookDiscount) {
        this.computerBookDiscount = computerBookDiscount;
    }

    public void setLanguageBookDiscount(LanguageBookDiscount languageBookDiscount) {
        this.languageBookDiscount = languageBookDiscount;
    }

    public void setNovelBookDiscount(NovelBookDiscount novelBookDiscount) {
        this.novelBookDiscount = novelBookDiscount;
    }

    public double showPrice(Book book){
        double price = book.getPrice();
        if(book instanceof ComputerBook){
            price = computerBookDiscount.discount(price);
        }else if(book instanceof LanguageBook){
            price = languageBookDiscount.discount(price);
        }else if(book instanceof NovelBook){
            price = novelBookDiscount.discount(price);
        }

        System.out.println(book.getClass().getSimpleName()+"  orig:"+book.getPrice()+"  now:"+price );

        return price;
    }
}
public class Book {
    private double price;

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
public class ComputerBook extends Book {
}
public class LanguageBook extends Book {
}
public class NovelBook extends Book {
}
public class BookShopTest {
    private BookShop bookShop;

    @Before
    public void init(){
        bookShop = new BookShop();
        bookShop.setComputerBookDiscount(new ComputerBookDiscount());
        bookShop.setLanguageBookDiscount(new LanguageBookDiscount());
        bookShop.setNovelBookDiscount(new NovelBookDiscount());
    }

    @Test
    public void test(){
        Book computerBook = new ComputerBook();
        computerBook.setPrice(200);
        Book languageBook = new LanguageBook();
        languageBook.setPrice(200);
        Book novelBook = new NovelBook();
        novelBook.setPrice(200);

        bookShop.showPrice(computerBook);
        bookShop.showPrice(languageBook);
        bookShop.showPrice(novelBook);
    }
}