2016-08-11 2 views
0

Недавно я столкнулся с проблемой, которую меня попросили разработать с использованием соответствующих шаблонов дизайна. Вышеуказанный отчет:Java Design Patterns Quiz

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. 

Я не могу понять, как спроектировать этот запрос. Это то, что я придумал:

Место представляет собой абстрактный класс.

Главная расширяет место

Отель простирается Место

FriendPlace расширяет Место

TVRemote класс

Место имеет TVRemote

Ключи является интерфейсом

КЛЮЧИ имеет метод р ССГ()

UpKey, DownKey, ForwardKey, BackKey классы, реализующие ключи

TVRemote имеет ключи

Там может быть больше ключей в TVRemote

Это то, что я мог думать, но неспособность включить шаблон дизайна здесь. Любые указания?

+1

Фасад картины? – lemon

+0

как будет выглядеть дизайн? –

+3

Я думаю, что место не имеет значения, потому что взаимодействие между телевизором и пультом дистанционного управления полностью не зависит от местоположения. – jetstream96

ответ

0

Упрощенный подход будет создавать интерфейс

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

, а затем создать определенные классы, которые будут осуществлять этот интерфейс для конкретных устройств

например

public class HomeRemote implements RemoteControl { 

public void up(){ 
.. 
} 

public vois down(){ 
.. 
} 

public void forward(){ 
.. 
} 

public void back(){ 
.. 
} 

} 

Однако

После нашего обсуждения - и после поиска немного больше, я склонен сейчас думать, что мост картина того, что просят здесь. Проверьте это - http://www.programcreek.com/2011/10/java-design-pattern-bridge/

Там абстрактный класс для дистанционного управления используются с базовой реализацией (вверх, вниз, вперед, назад) Тогда каждый конкретный TVRemote расширяет абстрактный класс, чтобы добавить больше/и устройств специальных функций.

Также обратите внимание, что телевизоры используют общий интерфейс, где описаны функции goUp(), goDown(), goForward(), goBack() и, возможно, on(), off()).

+0

Как удаленный дом, отличный от местоположения друга, когда все, что у них есть, это 4 команды и взаимодействие с одним и тем же устройством? –

+0

Устройства на самом деле разные - если у меня дома есть LG, у вас есть Samsung или что-то еще - они разработаны совершенно по-разному. 4 команды, к которым вы обращаетесь, являются общим интерфейсом, но каждое устройство реализует его по-разному (на низком уровне). Конечный пользователь не заботится о фактической реализации - он/она просто использует интерфейс, – Plirkee

+0

Право. Конечным пользователям не нужно беспокоиться о реализации, но я чувствую, что все команды имеют одинаковую функциональность, несмотря на необходимость работать с различными устройствами модели. Клавиша «Вверх» будет выполняться только так же, как и «Вниз», «Вперед» и «Назад». Я полагаю, что нет необходимости в отдельной удаленной реализации. У Remote есть ключ, и когда вы нажимаете() UpKey, он выполняет операцию. –

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 с:

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)

0

Вы должны использовать шаблон command. Обычно он имеет Invoker, Client, Command и Receiver. Ниже приведены классы, которые могут вам понадобиться.

Команда

public interface ICommand { 
    void execute(); 
} 

Invoker

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"; 
    } 
} 

Client

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 
} 

ИСПЫТАНИЙ

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); 
    } 
} 

Если вам dd любые дополнительные ключи к пульту дистанционного управления вам не нужно касаться какой-либо из существующих команд или invoker. Вам просто нужно добавить его в клиенте. Это соответствует Open Close principle. Если у вас есть другой пульт для каждого места, сделайте его аргументом конструктора, поэтому вам не нужно менять какие-либо другие классы.