Java设计模式测验

时间:2016-08-11 06:05:19

标签: java algorithm oop design-patterns

最近我遇到了一个问题,我被要求使用适当的设计模式进行设计。问题陈述是:

Implement a remote control of TV. 
Any remote control we use, either at home/hotel or at a friend’s place, 
we just pick up the TV remote control and start pressing Up and Down 
or Forward and Back keys to change the channels.
Choose a suitable design pattern for implementation of this problem.

我无法弄清楚如何设计这个问题。这就是我想出的:

  

Place是一个抽象类。

     

Home扩展地点

     

酒店扩展地点

     

FriendPlace扩展了地方

     

TVRemote是一个班级

     

Place有TVRemote

     

Keys是一个界面

     

Keys有一个方法按()

     

UpKey,DownKey,ForwardKey,BackKey是实现Keys的类

     

TVRemote有钥匙

     

TVRemote中可能有更多按键

这是我能想到的,但却无法在此处加入设计模式。有什么指导吗?

3 个答案:

答案 0 :(得分:0)

一种简单的方法是创建一个接口

interface RemoteControl 
{
public void up(); 
public vois down();
public void forward();
public void back();
} 

然后创建将为特定设备实现该接口的特定类

e.g。

public class HomeRemote implements RemoteControl {

public void up(){
..
} 

public vois down(){
..
}

public void forward(){
..
}

public void back(){
..
}

}

然而

经过我们的讨论 - 经过多次搜索后,我倾向于认为 Bridge 模式就是这里要求的。 看看这个 - http://www.programcreek.com/2011/10/java-design-pattern-bridge/

用于远程控制的抽象类与基本实现(向上,向下,向前,向后)一起使用 然后,每个特定的TVRemote扩展抽象类,以添加更多/和设备特定的功能。

另请注意,电视正在使用通用接口,其中描述了goUp(),goDown(),goForward(),goBack()以及可能的on(),off())函数。

答案 1 :(得分:0)

一些观察结果:

  • 不同的遥控器可能有不同数量的按钮
  • 不同的按钮执行不同的操作
  • 遥控器应该忘记行动的执行方式
  • 应该可以通过为按钮分配不同的动作或支持不同的设备来重新编程遥控器

这种情况最直接的模式是Command。可以创建特定的Command实现,然后将Command分配给按钮:

public interface Command {
    void Execute();
}
public class Button {
    private readonly Command command;
    public Button(Command command) {
        this.command = command;
    }
    public void Press() {
        this.command.Execute();
    }
 }
 public class Remote {
     public Button ButtonPlaceholder1 { get; set; }
     public Button ButtonPlaceholder2 { get; set; }
     public Button ButtonPlaceholder3 { get; set; }
     public Button ButtonPlaceholder4 { get; set; }
 }

那么,拥有Button课程有什么好处?好吧,我们假设您要引入一个滑块按钮,可以上下移动。在这种情况下,您将使用两个Command s配置它:

public class SliderButton {
    public SliderButton(Command up, Command down) {
        this.commandUp = up;
        this.commandDown = down;
    }
    public void Up() {
        this.commandUp.Execute();
    }
    public void Down() {
        this.commandDown.Execute();
    }
}

关于这次访谈的有趣的后续问题是,"如何实现一个按钮,取消按下前一个按钮所做的动作? (例如我正在观看ESPN频道,但是在比赛之间有一个中断,所以我切换到MTV,但我想偶尔检查一下是否已经结束,如果没有,请回到MTV)

答案 2 :(得分:0)

您应该在此处使用command模式。通常它有Invoker,Client,Command和Receiver。以下是您可能需要的课程。

<强>命令

public interface ICommand {
    void execute();
}

<强>调用程序

public class RemoteControl {
    Map<Key, ICommand> commandsByKey;

    public RemoteControl() {
        commandsByKey = new HashMap<>();
    }

    public void setCommand(Key key, ICommand command) {
        commandsByKey.put(key, command);
    }

    public void press(Key key) throws Exception {
        ICommand command = commandsByKey.get(key);
        if(command == null)
            throw new Exception("Invalid Key");
        command.execute();
    }
}

<强>接收机

public class TV {
    private String brand;

    public TV(String brand) {
        this.brand = brand;
    }

    @Override
    public String toString() {
        return brand + " TV";
    }
}

<强>客户端

public abstract class Place {
    private TV tv;
    private RemoteControl remoteControl;

    public Place(TV tv) {
        this.tv = tv;
        this.remoteControl = new RemoteControl();

        remoteControl.setCommand(Key.UP, new UpCommand(this.tv));
        remoteControl.setCommand(Key.FORWARD, new ForwardCommand(this.tv));
        remoteControl.setCommand(Key.DOWN, new DownCommand(this.tv));
        remoteControl.setCommand(Key.BACK, new BackCommand(this.tv));
    }

    public TV getTv() {
        return tv;
    }

    public RemoteControl getRemoteControl() {
        return remoteControl;
    }
}

public class Home extends Place {
    public Home() {
        super(new TV("Sony"));
    }
}

public class Hotel extends Place {

    public Hotel() {
        super(new TV("LG"));
    }
}

具体命令

public class UpCommand implements ICommand {
    private TV tv;

    public UpCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        System.out.println("Up Command  - " + tv);
    }

}


public class DownCommand implements ICommand {
    private TV tv;

    public DownCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        System.out.println("Down Command  - " + tv);
    }
}


public class ForwardCommand implements ICommand {
    private TV tv;

    public ForwardCommand(TV tv) {
        this.tv = tv;
    }
    @Override
    public void execute() {
        System.out.println("Forward Command  - " + tv);

    }

}


public class BackCommand implements ICommand {
    private TV tv;

    public BackCommand(TV tv) {
        this.tv = tv;
    }

    @Override
    public void execute() {
        System.out.println("Back Command  - " + tv);
    }

}

<强>键

public enum Key {
    UP, DOWN, FORWARD, BACK
}

<强> TEST

public class RemoteTest {
    public static void main(String[] args) throws Exception {
        Place home = new Home();
        home.getRemoteControl().press(Key.UP);
        home.getRemoteControl().press(Key.DOWN);
        home.getRemoteControl().press(Key.BACK);

        Hotel hotel = new Hotel();
        hotel.getRemoteControl().press(Key.UP);
    }
}

如果您向遥控器添加任何其他键,则无需触摸任何现有命令或调用者。您只需要在客户端中添加它。这符合Open Close principle。如果每个地方都有不同的遥控器,那么将其作为构造函数参数,这样就不需要更改任何其他类。