尝试在MVC示例中使用Java lambda表达式,don';I don’我不知道我还能做什么?
下面的MVC示例来自Head First Design Patterns一书。尝试在MVC示例中使用Java lambda表达式,don';I don’我不知道我还能做什么?,java,design-patterns,model-view-controller,lambda,functional-programming,Java,Design Patterns,Model View Controller,Lambda,Functional Programming,下面的MVC示例来自Head First Design Patterns一书。 此MVC示例关注观察者模式(模型与视图/控制器之间) 策略模式(控制器为策略)。 今天我想尝试使用lambda表达式来改进代码, 我只能将视图中的Actionperformed部分更改为lambda表达式。 我不知道在本例中是否还有更多地方可以使用lambda表达式? 示例的开头 型号零件: 主题: public interface BeatModelInterface { void initialize()
此MVC示例关注观察者模式(模型与视图/控制器之间) 策略模式(控制器为策略)。
今天我想尝试使用lambda表达式来改进代码, 我只能将视图中的Actionperformed部分更改为lambda表达式。
我不知道在本例中是否还有更多地方可以使用lambda表达式?
示例的开头
型号零件:
主题:
public interface BeatModelInterface {
void initialize();
void on();
void off();
void setBPM(int bpm);
int getBPM();
void registerObserver(BeatObserver o);
void removeObserver(BeatObserver o);
void registerObserver(BPMObserver o);
void removeObserver(BPMObserver o);
}
public interface BeatObserver {
void updateBeat();
}
public interface BPMObserver {
void updateBPM();
}
import javax.sound.midi.*;
import java.util.*;
public class BeatModel implements BeatModelInterface, MetaEventListener {
Sequencer sequencer;
ArrayList<BeatObserver> beatObservers = new ArrayList<BeatObserver>();
ArrayList<BPMObserver> bpmObservers = new ArrayList<BPMObserver>();
int bpm = 90;
Sequence sequence;
Track track;
public void initialize() {
setUpMidi();
buildTrackAndStart();
}
public void on() {
System.out.println("Starting the sequencer");
sequencer.start();
setBPM(90);
}
public void off() {
setBPM(0);
sequencer.stop();
}
public void setBPM(int bpm) {
this.bpm = bpm;
sequencer.setTempoInBPM(getBPM());
notifyBPMObservers();
}
public int getBPM() {
return bpm;
}
void beatEvent() {
notifyBeatObservers();
}
public void registerObserver(BeatObserver o) {
beatObservers.add(o);
}
public void notifyBeatObservers() {
for(int i = 0; i < beatObservers.size(); i++) {
BeatObserver observer = (BeatObserver)beatObservers.get(i);
observer.updateBeat();
}
}
public void registerObserver(BPMObserver o) {
bpmObservers.add(o);
}
public void notifyBPMObservers() {
for(int i = 0; i < bpmObservers.size(); i++) {
BPMObserver observer = (BPMObserver)bpmObservers.get(i);
observer.updateBPM();
}
}
public void removeObserver(BeatObserver o) {
int i = beatObservers.indexOf(o);
if (i >= 0) {
beatObservers.remove(i);
}
}
public void removeObserver(BPMObserver o) {
int i = bpmObservers.indexOf(o);
if (i >= 0) {
bpmObservers.remove(i);
}
}
public void meta(MetaMessage message) {
if (message.getType() == 47) {
beatEvent();
sequencer.start();
setBPM(getBPM());
}
}
public void setUpMidi() {
try {
sequencer = MidiSystem.getSequencer();
sequencer.open();
sequencer.addMetaEventListener(this);
sequence = new Sequence(Sequence.PPQ,4);
track = sequence.createTrack();
sequencer.setTempoInBPM(getBPM());
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
} catch(Exception e) {
e.printStackTrace();
}
}
public void buildTrackAndStart() {
int[] trackList = {35, 0, 46, 0};
sequence.deleteTrack(null);
track = sequence.createTrack();
makeTracks(trackList);
track.add(makeEvent(192,9,1,0,4));
try {
sequencer.setSequence(sequence);
} catch(Exception e) {
e.printStackTrace();
}
}
public void makeTracks(int[] list) {
for (int i = 0; i < list.length; i++) {
int key = list[i];
if (key != 0) {
track.add(makeEvent(144,9,key, 100, i));
track.add(makeEvent(128,9,key, 100, i+1));
}
}
}
public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {
MidiEvent event = null;
try {
ShortMessage a = new ShortMessage();
a.setMessage(comd, chan, one, two);
event = new MidiEvent(a, tick);
} catch(Exception e) {
e.printStackTrace();
}
return event;
}
}
具体主题:
public interface BeatModelInterface {
void initialize();
void on();
void off();
void setBPM(int bpm);
int getBPM();
void registerObserver(BeatObserver o);
void removeObserver(BeatObserver o);
void registerObserver(BPMObserver o);
void removeObserver(BPMObserver o);
}
public interface BeatObserver {
void updateBeat();
}
public interface BPMObserver {
void updateBPM();
}
import javax.sound.midi.*;
import java.util.*;
public class BeatModel implements BeatModelInterface, MetaEventListener {
Sequencer sequencer;
ArrayList<BeatObserver> beatObservers = new ArrayList<BeatObserver>();
ArrayList<BPMObserver> bpmObservers = new ArrayList<BPMObserver>();
int bpm = 90;
Sequence sequence;
Track track;
public void initialize() {
setUpMidi();
buildTrackAndStart();
}
public void on() {
System.out.println("Starting the sequencer");
sequencer.start();
setBPM(90);
}
public void off() {
setBPM(0);
sequencer.stop();
}
public void setBPM(int bpm) {
this.bpm = bpm;
sequencer.setTempoInBPM(getBPM());
notifyBPMObservers();
}
public int getBPM() {
return bpm;
}
void beatEvent() {
notifyBeatObservers();
}
public void registerObserver(BeatObserver o) {
beatObservers.add(o);
}
public void notifyBeatObservers() {
for(int i = 0; i < beatObservers.size(); i++) {
BeatObserver observer = (BeatObserver)beatObservers.get(i);
observer.updateBeat();
}
}
public void registerObserver(BPMObserver o) {
bpmObservers.add(o);
}
public void notifyBPMObservers() {
for(int i = 0; i < bpmObservers.size(); i++) {
BPMObserver observer = (BPMObserver)bpmObservers.get(i);
observer.updateBPM();
}
}
public void removeObserver(BeatObserver o) {
int i = beatObservers.indexOf(o);
if (i >= 0) {
beatObservers.remove(i);
}
}
public void removeObserver(BPMObserver o) {
int i = bpmObservers.indexOf(o);
if (i >= 0) {
bpmObservers.remove(i);
}
}
public void meta(MetaMessage message) {
if (message.getType() == 47) {
beatEvent();
sequencer.start();
setBPM(getBPM());
}
}
public void setUpMidi() {
try {
sequencer = MidiSystem.getSequencer();
sequencer.open();
sequencer.addMetaEventListener(this);
sequence = new Sequence(Sequence.PPQ,4);
track = sequence.createTrack();
sequencer.setTempoInBPM(getBPM());
sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
} catch(Exception e) {
e.printStackTrace();
}
}
public void buildTrackAndStart() {
int[] trackList = {35, 0, 46, 0};
sequence.deleteTrack(null);
track = sequence.createTrack();
makeTracks(trackList);
track.add(makeEvent(192,9,1,0,4));
try {
sequencer.setSequence(sequence);
} catch(Exception e) {
e.printStackTrace();
}
}
public void makeTracks(int[] list) {
for (int i = 0; i < list.length; i++) {
int key = list[i];
if (key != 0) {
track.add(makeEvent(144,9,key, 100, i));
track.add(makeEvent(128,9,key, 100, i+1));
}
}
}
public MidiEvent makeEvent(int comd, int chan, int one, int two, int tick) {
MidiEvent event = null;
try {
ShortMessage a = new ShortMessage();
a.setMessage(comd, chan, one, two);
event = new MidiEvent(a, tick);
} catch(Exception e) {
e.printStackTrace();
}
return event;
}
}
实施战略:
public class BeatController implements ControllerInterface {
BeatModelInterface model;
DJView view;
public BeatController(BeatModelInterface model) {
this.model = model;
view = new DJView(this, model);
view.createView();
view.createControls();
view.disableStopMenuItem();
view.enableStartMenuItem();
model.initialize();
}
public void start() {
model.on();
view.disableStartMenuItem();
view.enableStopMenuItem();
}
public void stop() {
model.off();
view.disableStopMenuItem();
view.enableStartMenuItem();
}
public void increaseBPM() {
int bpm = model.getBPM();
model.setBPM(bpm + 1);
}
public void decreaseBPM() {
int bpm = model.getBPM();
model.setBPM(bpm - 1);
}
public void setBPM(int bpm) {
model.setBPM(bpm);
}
}
最后我们将MVC结合在一起:
public class DJTestDrive {
public static void main (String[] args) {
BeatModelInterface model = new BeatModel();
ControllerInterface controller = new BeatController(model);
}
}
----示例的结尾-----
问题:
我只能将视图中的actionperformed部分更改为lambda表达式,如下所示:
原件:
menuBar = new JMenuBar();
menu = new JMenu("DJ Control");
startMenuItem = new JMenuItem("Start");
menu.add(startMenuItem);
startMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
controller.start();
}
});
stopMenuItem = new JMenuItem("Stop");
menu.add(stopMenuItem);
stopMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
controller.stop();
}
});
JMenuItem exit = new JMenuItem("Quit");
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
});
到lambda表达式:
menuBar = new JMenuBar();
menu = new JMenu("DJ Control");
startMenuItem = new JMenuItem("Start");
menu.add(startMenuItem);
startMenuItem.addActionListener((ActionEvent event) -> {
controller.start();
});
stopMenuItem = new JMenuItem("Stop");
menu.add(stopMenuItem);
stopMenuItem.addActionListener((ActionEvent event) -> {
controller.stop();
});
JMenuItem exit = new JMenuItem("Quit");
exit.addActionListener((ActionEvent event) -> {
System.exit(0);
});
在这种复杂的示例中,还有其他地方可以使用lambda表达式吗?或者我不应该在这样复杂的情况下使用lambda表达式
非常感谢您的耐心在lambda中,参数的类型不是强制性的,括号是可选的,因为只声明了一个参数。因此您可以编写
startMenuItem.addActionListener(事件->{controller.start();})
@davidxxx非常感谢您的建议:)如果您认为本例中有更多地方我可以换成lambda,请随时通知我。我是这个领域的新手,我会非常感谢你的帮助!提示:一般来说,当您的接口只包含一个方法时,它是一个功能接口(可以注释为@functioninterface
),基本上可以与lambda互换使用。@Joel非常感谢您的提示!因此,在这个包含多个方法的多个接口的复杂示例中,我不应该使用lambda,对吗?@YSL这不是我的意思-您可以随时使用lambda(或者说:随时编译)。实际上,乍一看,我认为您的BeatObserver
/BPMObserver
可以被视为功能接口,但考虑到它们的实现方式,这是不正确的