Week 4
week 4
进阶知识
设计模式
行为型设计模式
- 模板方法模式
模板方法模式是一种行为型设计模式,它在一个抽象类中定义了一个算法的骨架,将一些步骤的具体实现延迟到子类中。这样使得子类可以在不改变该算法结构的情况下,重新定义算法中的某些步骤。
首先,我们创建一个抽象类,定义算法的骨架和一些抽象方法:
public abstract class AbstractTemplate {
// 模板方法,定义算法的骨架
public final void templateMethod() {
step1();
step2();
step3();
}
// 具体步骤1
protected abstract void step1();
// 具体步骤2
protected abstract void step2();
// 具体步骤3
protected void step3() {
System.out.println("执行步骤3");
}
}
接下来,我们创建一个具体的子类,实现抽象方法:
public class ConcreteTemplate extends AbstractTemplate {
@Override
protected void step1() {
System.out.println("执行步骤1");
}
@Override
protected void step2() {
System.out.println("执行步骤2");
}
}
最后,我们在主函数中使用模板方法模式:
public class Main {
public static void main(String[] args) {
AbstractTemplate template = new ConcreteTemplate();
template.templateMethod();
}
}
运行结果:
执行步骤1
执行步骤2
执行步骤3
- 命令模式
命令模式是一种行为设计模式,它允许您将一个请求封装为一个对象,从而使您可以使用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
首先,我们创建一个命令接口:
public interface Command {
void execute();
void undo();
}
然后,我们创建一个具体的命令类,实现命令接口:
public class ConcreteCommand implements Command {
private Receiver receiver;
private String command;
public ConcreteCommand(Receiver receiver, String command) {
this.receiver = receiver;
this.command = command;
}
@Override
public void execute() {
receiver.action(command);
}
@Override
public void undo() {
receiver.undoAction();
}
}
接下来,我们创建一个接收者类,用于执行和撤销命令:
public class Receiver {
public void action(String command) {
System.out.println("执行命令:" + command);
}
public void undoAction() {
System.out.println("撤销命令");
}
}
最后,我们在主函数中使用命令模式:
public class CommandPatternDemo {
public static void main(String[] args) {
Receiver receiver = new Receiver();
String command = "打印Hello World";
Command commandObj = new ConcreteCommand(receiver, command);
commandObj.execute();
commandObj.undo();
}
}
运行上述代码,输出结果如下:
执行命令:打印Hello World
撤销命令
- 迭代器模式
迭代器模式是一种行为设计模式,它提供了一种方法来顺序访问一个聚合对象(如列表、数组等)中的各个元素,而又不暴露该对象的内部表示。
首先,我们创建一个可迭代的对象类:
import java.util.Iterator;
public class IterableCollection<E> implements Iterable<E> {
private E[] elements;
public IterableCollection(E[] elements) {
this.elements = elements;
}
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < elements.length;
}
@Override
public E next() {
System.out.print("my-iterator:");
return elements[index++];
}
};
}
}
接下来,我们在主函数中使用迭代器模式:
public class IteratorPatternDemo {
public static void main(String[] args) {
Integer[] numbers = {1, 2, 3, 4, 5};
IterableCollection<Integer> iterableCollection = new IterableCollection<>(numbers);
Iterator<Integer> iterator = iterableCollection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
运行上述代码,输出结果如下:
my-iterator:1
my-iterator:2
my-iterator:3
my-iterator:4
my-iterator:5
- 观察者模式
观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
首先,我们创建一个主题接口:
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
然后,我们创建一个具体的主题类:
import java.util.ArrayList;
import java.util.List;
public class ConcreteSubject implements Subject {
private List<Observer> observers;
private int state;
public ConcreteSubject() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
public void setState(int state) {
this.state = state;
notifyObservers();
}
}
接下来,我们创建一个观察者接口:
public interface Observer {
void update(int state);
}
然后,我们创建一个具体的观察者类:
public class ConcreteObserver implements Observer {
private int state;
@Override
public void update(int state) {
this.state = state;
System.out.println("状态已更新为:" + state);
}
}
最后,我们在主函数中使用观察者模式:
public class ObserverPatternDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver();
Observer observer2 = new ConcreteObserver();
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setState(1);
subject.setState(2);
}
}
运行上述代码,输出结果如下:
状态已更新为:1
状态已更新为:1
状态已更新为:2
状态已更新为:2
- 中介者模式
中介者模式是一种行为设计模式,它通过引入一个中介对象来封装一系列对象的交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
观察者模式是单向的,一堆对象观察一个东西,等待这个东西的更新通知;中介者模式,一堆对象谁都能发送广播通知,其他对象接到通知后进行相应的操作。
首先,我们创建一个中介者接口:
public interface Mediator {
void send(String message, Colleague colleague);
}
然后,我们创建一个具体的中介者类:
import java.util.ArrayList;
import java.util.List;
public class ConcreteMediator implements Mediator {
private List<Colleague> colleagues;
public ConcreteMediator() {
colleagues = new ArrayList<>();
}
@Override
public void send(String message, Colleague colleague) {
for (Colleague c : colleagues) {
if (c != colleague) {
c.receive(message);
}
}
}
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
}
接下来,我们创建一个具体的同事类:
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
public abstract void send(String message);
public abstract void receive(String message);
}
然后,我们创建两个具体的同事类:
public class ConcreteColleagueA extends Colleague {
public ConcreteColleagueA(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
System.out.println("同事A发送消息:" + message);
}
@Override
public void receive(String message) {
System.out.println("同事A接收消息:" + message);
}
}
public class ConcreteColleagueB extends Colleague {
public ConcreteColleagueB(Mediator mediator) {
super(mediator);
}
@Override
public void send(String message) {
System.out.println("同事B发送消息:" + message);
}
@Override
public void receive(String message) {
System.out.println("同事B接收消息:" + message);
}
}
最后,我们在主函数中使用中介者模式:
public class MediatorPatternDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
ConcreteColleagueA colleagueA = new ConcreteColleagueA(mediator);
ConcreteColleagueB colleagueB = new ConcreteColleagueB(mediator);
mediator.addColleague(colleagueA);
mediator.addColleague(colleagueB);
mediator.send("hello", colleagueA); // colleagueA 发送广播消息
mediator.send("world", colleagueB);
}
}
运行上述代码,输出结果如下:
同事B接收消息:hello
同事A接收消息:world
- 备忘录模式
备忘录模式(Memento Pattern)是一种行为型设计模式,它通过在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。
首先,我们创建一个Memento
类来存储对象的状态:
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
接下来,我们创建一个Originator
接口,它包含一个createState
方法用于创建状态,以及一个saveState
方法用于保存状态:
public interface Originator {
Memento createState();
void saveState(Memento memento);
void restoreState(Memento memento);
}
然后,我们创建一个具体的Originator
实现,例如Game
类:
public class Game implements Originator {
private String state;
@Override
public Memento createState() {
return new Memento(state);
}
@Override
public void saveState(Memento memento) {
this.state = memento.getState();
}
@Override
public void restoreState(Memento memento) {
this.state = memento.getState();
}
}
最后,我们创建一个MementoHolder
类,用于保存和恢复Memento
对象:
public class MementoHolder {
private Memento memento;
public MementoHolder(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
}
使用示例:
public class Main {
public static void main(String[] args) {
Game game = new Game();
game.saveState(game.createState()); // 保存当前状态
game.state = "New State"; // 更改状态
Memento memento = game.createState(); // 创建新状态的Memento对象
game.restoreState(memento); // 恢复之前保存的状态
System.out.println(game.state); // 输出:New State
}
}
- 解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,它通过定义一个语法表示,然后使用解释器来解释该语法表示。
首先,我们创建一个Expression
接口,用于表示表达式:
public interface Expression {
int interpret();
}
接下来,我们创建一些具体的表达式实现,例如加法、减法和乘法:
public class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret() {
return left.interpret() + right.interpret();
}
}
然后,我们创建一个Context
类,用于存储解释器的上下文信息:
public class Context {
private Expression expression;
public void setExpression(Expression expression) {
this.expression = expression;
}
public int getResult() {
return expression.interpret();
}
}
最后,我们可以使用以下代码来测试解释器模式:
public class InterpreterPatternDemo {
public static void main(String[] args) {
Expression add = new AddExpression(new Integer(3), new Integer(5));
Context context = new Context();
context.setExpression(add);
System.out.println("Result: " + context.getResult()); // 输出:Result: 8
}
}
- 状态模式
状态模式(State Pattern)是一种行为型设计模式,它允许对象在其内部状态改变时改变它的行为。这种模式主要用于实现有限状态机。
首先,我们创建一个State
接口,用于表示状态:
public interface State {
void handle(Context context);
}
接下来,我们创建一些具体的State
实现,例如StartState
、RunningState
和StopState
:
public class StartState implements State {
@Override
public void handle(Context context) {
System.out.println("开始执行");
context.setState(new RunningState());
}
}
public class RunningState implements State {
@Override
public void handle(Context context) {
System.out.println("正在运行");
context.setState(new StopState());
}
}
public class StopState implements State {
@Override
public void handle(Context context) {
System.out.println("停止执行");
}
}
然后,我们创建一个Context
类,用于维护状态:
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public void setState(State state) {
this.state = state;
}
public void request() {
state.handle(this);
}
}
最后,我们可以使用以下代码来测试状态模式:
public class StatePatternDemo {
public static void main(String[] args) {
Context context = new Context(new StartState());
context.request(); // 输出:开始执行
context.request(); // 输出:正在运行
context.request(); // 输出:停止执行
}
}
- 策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换。策略模式让算法的变化独立于使用它们的客户端。
首先,我们创建一个Strategy
接口,用于表示策略:
public interface Strategy {
void execute();
}
接下来,我们创建一些具体的策略实现,例如ConcreteStrategyA
和ConcreteStrategyB
:
public class ConcreteStrategyA implements Strategy {
@Override
public void execute() {
System.out.println("执行策略A");
}
}
public class ConcreteStrategyB implements Strategy {
@Override
public void execute() {
System.out.println("执行策略B");
}
}
然后,我们创建一个Context
类,用于维护策略:
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
最后,我们可以使用以下代码来测试策略模式:
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategyA());
context.executeStrategy(); // 输出:执行策略A
context.setStrategy(new ConcreteStrategyB());
context.executeStrategy(); // 输出:执行策略B
}
}
- 责任链模式
责任链模式(Chain of Responsibility)是一种行为型设计模式,它使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
首先,我们创建一个Handler
接口,用于表示处理器:
public interface Handler {
void setNext(Handler handler);
void handleRequest(String request);
}
接下来,我们创建一些具体的Handler
实现,例如ConcreteHandlerA
和ConcreteHandlerB
:
public class ConcreteHandlerA implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handleRequest(String request) {
if ("A".equals(request)) {
System.out.println("处理器A处理请求");
} else if (next != null) {
next.handleRequest(request);
} else {
System.out.println("没有处理器可以处理该请求");
}
}
}
public class ConcreteHandlerB implements Handler {
private Handler next;
@Override
public void setNext(Handler handler) {
this.next = handler;
}
@Override
public void handleRequest(String request) {
if ("B".equals(request)) {
System.out.println("处理器B处理请求");
} else if (next != null) {
next.handleRequest(request);
} else {
System.out.println("没有处理器可以处理该请求");
}
}
}
然后,我们创建一个Context
类,用于维护处理器:
public class Context {
private Handler handler;
public Context(Handler handler) {
this.handler = handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
public void handleRequest(String request) {
handler.handleRequest(request);
}
}
最后,我们可以使用以下代码来测试责任链模式:
public class ChainOfResponsibilityPatternDemo {
public static void main(String[] args) {
Context context = new Context(new ConcreteHandlerA());
context.handleRequest("A"); // 输出:处理器A处理请求
context.setHandler(new ConcreteHandlerB());
context.handleRequest("B"); // 输出:处理器B处理请求
context.handleRequest("C"); // 输出:没有处理器可以处理该请求
}
}
- 访问者模式
访问者模式(Visitor Pattern)是一种行为型设计模式,它允许在不改变对象结构的情况下,定义一组操作来处理具有相同接口的对象。这有助于将数据结构和操作分离,使得算法可以独立于使用它的数据结构。
首先,我们创建一个Element
接口,用于表示元素:
public interface Element {
void accept(Visitor visitor);
}
接下来,我们创建一些具体的元素实现,例如ElementA
和ElementB
:
public class ElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
public class ElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
然后,我们创建一个Visitor
接口,用于表示访问者:
public interface Visitor {
void visit(ElementA elementA);
void visit(ElementB elementB);
}
接下来,我们创建一些具体的访问者实现,例如ConcreteVisitorA
和ConcreteVisitorB
:
public class ConcreteVisitorA implements Visitor {
@Override
public void visit(ElementA elementA) {
System.out.println("访问者A处理元素A");
}
@Override
public void visit(ElementB elementB) {
System.out.println("访问者A处理元素B");
}
}
public class ConcreteVisitorB implements Visitor {
@Override
public void visit(ElementA elementA) {
System.out.println("访问者B处理元素A");
}
@Override
public void visit(ElementB elementB) {
System.out.println("访问者B处理元素B");
}
}
最后,我们可以使用以下代码来测试访问者模式:
public class VisitorPatternDemo {
public static void main(String[] args) {
Element elementA = new ElementA();
Element elementB = new ElementB();
Visitor visitorA = new ConcreteVisitorA();
Visitor visitorB = new ConcreteVisitorB();
elementA.accept(visitorA); // 输出:访问者A处理元素A
elementA.accept(visitorB); // 输出:访问者B处理元素A
elementB.accept(visitorA); // 输出:访问者A处理元素B
elementB.accept(visitorB); // 输出:访问者B处理元素B
}
}
网络编程
常用协议
tcp、udp、http、https、ftp、smtp
- Java实现ftp
服务器端代码:
import org.apache.commons.net.ftp.FTPServer;
import java.io.IOException;
public class FTPServerExample {
public static void main(String[] args) throws IOException {
// 创建FTP服务器对象并监听指定端口
FTPServer server = new FTPServer();
server.listen(21);
System.out.println("FTP Server started on port 21");
// 等待客户端连接
while (true) {
FTPClient client = server.accept();
System.out.println("New client connected: " + client.getRemoteAddress());
// 处理客户端请求
handleClientRequest(client);
// 关闭客户端连接
client.close();
}
}
private static void handleClientRequest(FTPClient client) throws IOException {
// 获取客户端请求的文件名
String fileName = client.getFileName();
if (fileName != null && fileName.endsWith(".txt")) {
// 读取本地文件内容并发送给客户端
byte[] buffer = new byte[4096];
int bytesRead = -1;
File localFile = new File("local-file.txt");
InputStream inputStream = new FileInputStream(localFile);
OutputStream outputStream = client.retrieveFileStream(fileName);
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
} else {
// 其他请求交给下一个处理器处理
nextHandler.handleClientRequest(client);
}
}
private static final NextHandler nextHandler = new NextHandler();
private static class NextHandler {
public void handleClientRequest(FTPClient client) {
// 处理其他类型的请求,例如列出目录、删除文件等
// ...
}
}
}
客户端代码:
import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
public class FTPClientExample {
public static void main(String[] args) {
// 创建FTP客户端对象并连接到FTP服务器
FTPClient client = new FTPClient();
try {
client.connect("localhost", 21);
System.out.println("Connected to FTP server");
// 登录FTP服务器
client.login("username", "password");
System.out.println("Logged in to FTP server");
// 切换到指定目录
client.changeWorkingDirectory("/path/to/directory");
System.out.println("Changed working directory");
// 下载文件
File localFile = new File("local-file.txt");
InputStream inputStream = new FileInputStream(localFile);
OutputStream outputStream = client.retrieveFileStream("remote-file.txt");
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
// 上传文件
File fileToUpload = new File("file-to-upload.txt");
InputStream fis = new FileInputStream(fileToUpload);
client.storeFile("remote-file.txt", fis);
fis.close();
// 删除文件
client.deleteFile("remote-file.txt");
// 断开连接
client.logout();
client.disconnect();
System.out.println("Disconnected from FTP server");
} catch (IOException e) {
e.printStackTrace();
}
}
}
这个示例代码演示了如何使用FTPClient类连接到FTP服务器、登录、切换目录、下载和上传文件以及断开连接。需要注意的是,在实际使用中,应该根据具体情况进行异常处理和资源管理。