最近我遇到了一个问题,我被要求使用适当的设计模式进行设计。问题陈述是:
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中可能有更多按键
这是我能想到的,但却无法在此处加入设计模式。有什么指导吗?
答案 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。如果每个地方都有不同的遥控器,那么将其作为构造函数参数,这样就不需要更改任何其他类。