Java八股文の设计模式
- 设计模式
设计模式
- 什么是设计模式?请列举一些常见的设计模式。
设计模式是软件设计中常用的一种思维模式,它描述了一类具有相似特征和解决思路的问题。
常见的设计模式包括单例模式、工厂模式、观察者模式、装饰器模式等。
- 请解释什么是单例模式,并提供一个线程安全的单例实现。
单例模式是一种常见的创建型模式,它确保一个类只有一个实例,并提供一个全局访问点。
以下是一个线程安全的懒汉式单例实现:
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- 什么是工厂模式?请列举工厂模式的几种变体。
工厂模式是一种常见的创建型模式,它将对象的创建和使用分离。
常见的工厂模式包括简单工厂模式、工厂方法模式和抽象工厂模式。
- 请解释什么是装饰器模式,并提供一个示例。
装饰器模式是一种结构型模式,它允许用户在不修改原始对象的情况下,以动态方式扩展其功能。
以下是一个装饰器模式的示例:
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing circle.");
}
}
class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
@Override
public void draw() {
decoratedShape.draw();
}
}
class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder();
}
private void setRedBorder() {
System.out.println("Setting red border.");
}
}
public class DecoratorPatternExample {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
circle.draw();
System.out.println("---");
redCircle.draw();
}
}
- 请解释什么是观察者模式,并提供一个示例。
观察者模式是一种行为型模式,它定义了对象之间的一对多关系,当一个对象的状态发生变化时,其相关对象会自动收到通知并更新。
以下是一个观察者模式的示例:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update();
}
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update() {
System.out.println(name + " received the update.");
}
}
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
public class ObserverPatternExample {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
subject.attach(observer1);
subject.attach(observer2);
subject.notifyObservers();
}
}
- 请解释什么是策略模式,并提供一个示例。
策略模式是一种行为型模式,它允许在运行时根据需求切换算法或策略。
以下是一个策略模式的示例:
interface Strategy {
int doOperation(int num1, int num2);
}
class AddStrategy implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
class SubtractStrategy implements Strategy {
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2) {
return strategy.doOperation(num1, num2);
}
}
public class StrategyPatternExample {
public static void main(String[] args) {
Context context = new Context(new AddStrategy());
System.out.println("5 + 2 = " + context.executeStrategy(5, 2));
context = new Context(new SubtractStrategy());
System.out.println("5 - 2 = " + context.executeStrategy(5, 2));
}
}
- 你在实际开发的过程中用过哪些设计模式?
当面试官问到你在实际开发中接触过哪些设计模式时,你可以按照以下步骤来回答这个问题:
步骤一:回答问题前的准备
● 细心回忆:回忆你在实际项目中遇到的设计问题和解决方案,并思考你应用了哪些设计模式。
● 项目准备:选择一个或多个具体的项目例子,这些例子最好能展示你在实际开发中对设计模式的应用和理解。
步骤二:回答问题的结构
你可以按如下结构组织你的回答,确保你的回答清晰有条理:● 简要介绍项目:首先,简要介绍你参与的项目的背景和规模,包括项目的类型(Web应用、移动应用等)、主要功能和技术栈等。
● 问题和挑战:描述在该项目中你面对的设计问题和挑战,阐明为什么需要使用设计模式来解决这些问题。
● 解决方案:详细解释你选择的设计模式及其原理,并展示如何应用到实际项目中。○ 描述设计模式的名称和概念。
○ 解释设计模式的工作原理,包括它是如何解决特定问题的。
○ 提供在实际项目中如何应用设计模式的具体示例代码。
● 结果和效益:说明使用设计模式的结果及其在项目中的效益。
○ 描述设计模式的应用对项目的影响。
○ 强调设计模式所带来的优势,比如代码的可维护性、可扩展性、重用性等。
步骤三:具体例子与解释
在回答问题时,可以结合具体的例子和相关代码来解释你在实际开发中的应用。下面是一个例子:● 介绍项目:我曾参与一个电商平台的开发项目,该项目采用Java技术栈,用于构建一个多平台的在线购物平台。该项目主要包括用户管理、商品管理、订单管理等功能模块。
● 问题和挑战:在该项目中,我们面临了一个问题,即如何实现订单模块中的支付系统。我们需要支持多种支付方式,并且需求可能随时发生变化。同时,我们还需要保持订单模块的稳定性和可扩展性。
● 解决方案:为了解决这个问题,我们采用了策略模式和工厂模式的组合应用。○ 策略模式的应用:我们定义了一个支付策略接口,通过实现不同的支付策略类来支持不同的支付方式,如微信支付、支付宝支付等。这样,在订单模块中,我们只需关注接口方法的调用,具体的支付逻辑由支付策略类来实现。这样的设计使我们能够动态切换支付方式,并且简化了代码。
○ 工厂模式的应用:我们使用工厂模式来创建支付策略对象。通过一个支付策略工厂类,我们可以根据用户选择的支付方式创建相应的支付策略对象。这样的设计保持了代码的灵活性,如新增一种支付方式时只需扩展工厂类而不影响其他模块。
● 结果和效益:通过应用策略模式和工厂模式,我们在订单模块中实现了一个灵活、可扩展的支付系统。当需求变化时,我们只需添加新的支付策略类和工厂方法即可,并且这样的设计提高了代码的可维护性和可测试性。
重要的是,不仅仅列出设计模式的名称,还要详细说明你在项目中的具体应用,以及应用所带来的优势和效益。这样可以体现出你对设计模式的理解和在实际项目中的应用能力。
- 什么是设计模式?
设计模式是在软件设计中经过验证的解决方案,可用于解决常见问题或模式。
它们提供了重用可维护代码的指导原则。
- 列举几个常用的设计模式?
单例模式、工厂模式、观察者模式、适配器模式、命令模式等。
- 解释单例模式的概念。
单例模式确保一个类只有一个实例,并提供一个全局访问点。
它用于限制对某个类只能创建一个对象的情况。
- 请提供一个单例模式的示例和实现。
以下是一个线程安全的懒汉式单例模式实现的例子:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 解释工厂模式的概念。
工厂模式是用于创建对象的创建模式,通过一个共同接口或基类创建具体类的实例。
- 请提供一个工厂模式的示例和实现。
以下是一个简单的工厂模式实现的例子:
public interface Shape {
void draw();
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a circle.");
}
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a rectangle.");
}
}
public class ShapeFactory {
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
}
return null;
}
}
- 解释观察者模式的概念。
观察者模式定义了对象之间的一对多依赖关系,使得当一个对象改变状态时,其依赖对象都会得到通知和自动更新。
- 请提供一个观察者模式的示例和实现。
以下是一个简单的观察者模式实现的例子:
import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update(String message);
}
public class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received a message: " + message);
}
}
public class Blog {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
- 解释适配器模式的概念。
适配器模式用于将一个类的接口转换成客户端所期望的另一个接口。
它通常用于现有类与不兼容类之间的协作。
- 请提供一个适配器模式的示例和实现。
以下是一个简单的适配器模式实现的例子:
public interface MediaPlayer {
void play(String audioType, String fileName);
}
public interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
public class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing vlc file: " + fileName);
}
@Override
public void playMp4(String fileName) {
// Do nothing
}
}
public class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
// Do nothing
}
@Override
public void playMp4(String fileName) {
System.out.println("Playing mp4 file: " + fileName);
}
}
public class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
public class AudioPlayer implements MediaPlayer {
MediaAdapter mediaAdapter;
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing mp3 file: " + fileName);
} else if (audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")) {
mediaAdapter = new MediaAdapter(audioType);
mediaAdapter.play(audioType, fileName);
} else {
System.out.println("Invalid media. " + audioType + " format not supported.");
}
}
}
- 解释命令模式的概念。
命令模式是一种行为设计模式,将请求封装为对象,从而使您可以对客户端参数化方法调用。
- 请提供一个命令模式的示例和实现。
以下是一个简单的命令模式实现的例子:
public interface Command {
void execute();
}
public class Light {
public void turnOn() {
System.out.println("Light turned on.");
}
public void turnOff() {
System.out.println("Light turned off.");
}
}
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
- 解释装饰器模式的概念。
装饰器模式允许向现有对象添加新功能,而无需对其进行更改。
它通过将对象包装在一个装饰器类中来实现。
- 请提供一个装饰器模式的示例和实现。
以下是一个简单的装饰器模式实现的例子:
public interface Coffee {
double cost();
String description();
}
public class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 1.0;
}
@Override
public String description() {
return "Simple coffee";
}
}
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee decoratedCoffee) {
this.decoratedCoffee = decoratedCoffee;
}
@Override
public double cost() {
return decoratedCoffee.cost();
}
@Override
public String description() {
return decoratedCoffee.description();
}
}
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public double cost() {
return super.cost() + 0.5;
}
@Override
public String description() {
return super.description() + ", with milk";
}
}
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee decoratedCoffee) {
super(decoratedCoffee);
}
@Override
public double cost() {
return super.cost() + 0.2;
}
@Override
public String description() {
return super.description() + ", with sugar";
}
}
- 解释策略模式的概念。
策略模式定义了算法族,分别封装起来,使它们之间可以互相替换。
它们之间可以相互替换,使得调用算法的业务逻辑与算法本身解耦。
- 请提供一个策略模式的示例和实现。
以下是一个简单的策略模式实现的例子:
public interface SortStrategy {
int[] sort(int[] numbers);
}
public class BubbleSortStrategy implements SortStrategy {
@Override
public int[] sort(int[] numbers) {
// Bubble sort implementation
return numbers;
}
}
public class QuickSortStrategy implements SortStrategy {
@Override
public int[] sort(int[] numbers) {
// Quick sort implementation
return numbers;
}
}
public class SortContext {
private SortStrategy strategy;
public SortContext(SortStrategy strategy) {
this.strategy = strategy;
}
public int[] sort(int[] numbers) {
return strategy.sort(numbers);
}
}
- 解释模板模式的概念。
模板模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中。
它允许子类在不改变算法结构的情况下重新定义算法的某些步骤。
- 请提供一个模板模式的示例和实现。
以下是一个简单的模板模式实现的例子:
public abstract class Game {
abstract void initialize();
abstract void startPlay();
abstract void endPlay();
public final void play() {
initialize();
startPlay();
endPlay();
}
}
public class Cricket extends Game {
@Override
void initialize() {
System.out.println("Cricket: Initializing the game...");
}
@Override
void startPlay() {
System.out.println("Cricket: Starting the game...");
}
@Override
void endPlay() {
System.out.println("Cricket: Ending the game...");
}
}
public class Football extends Game {
@Override
void initialize() {
System.out.println("Football: Initializing the game...");
}
@Override
void startPlay() {
System.out.println("Football: Starting the game...");
}
@Override
void endPlay() {
System.out.println("Football: Ending the game...");
}
}
- 解释责任链模式的概念。
责任链模式为请求的发送者和接收者之间提供了一种解耦的方式。
请求会沿着链传递,直到找到可以处理它的对象。
- 请提供一个责任链模式的示例和实现。
以下是一个简单的责任链模式实现的例子:
public abstract class Logger {
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(String message, int level) {
if (this.level <= level) {
writeMessage(message);
}
if (nextLogger != null) {
nextLogger.logMessage(message, level);
}
}
abstract protected void writeMessage(String message);
}
public class ConsoleLogger extends Logger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void writeMessage(String message) {
System.out.println("Console Logger: " + message);
}
}
public class FileLogger extends Logger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void writeMessage(String message) {
System.out.println("File Logger: " + message);
}
}
public class ErrorLogger extends Logger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void writeMessage(String message) {
System.out.println("Error Logger: " + message);
}
}
- 解释备忘录模式的概念。
备忘录模式用于捕获一个对象的内部状态,并在以后需要时将其恢复。
它提供了保存和还原对象状态的能力。
- 请提供一个备忘录模式的示例和实现。
以下是一个简单的备忘录模式实现的例子:
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
}
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
}
public Memento saveToMemento() {
return new Memento(state);
}
public void restoreFromMemento(Memento memento) {
state = memento.getState();
}
}
public class Caretaker {
private Memento memento;
public void setMemento(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
}
- 解释迭代器模式的概念。
迭代器模式提供了一种顺序访问集合对象元素的方式,而无需暴露其底层表示。
- 请提供一个迭代器模式的示例和实现。
以下是一个简单的迭代器模式实现的例子:
public interface Iterator {
boolean hasNext();
Object next();
}
public interface Container {
Iterator getIterator();
}
public class NameRepository implements Container {
private String[] names = {"John", "Mary", "Tom"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
private int index;
@Override
public boolean hasNext() {
return index < names.length;
}
@Override
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
- 解释享元模式的概念。
享元模式用于有效地支持大量细粒度对象的共享。
它以共享的方式高效地支持大量的细粒度对象。
- 请提供一个享元模式的示例和实现。
以下是一个简单的享元模式实现的例子:
import java.util.HashMap;
import java.util.Map;
public interface Shape {
void draw();
}
public class Circle implements Shape {
private String color;
private int x;
private int y;
private int radius;
public Circle(String color) {
this.color = color;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setRadius(int radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing circle: Color " + color + ", X: " + x + ", Y: " + y + ", Radius: " + radius);
}
}
public class ShapeFactory {
private static final Map<String, Shape> circleMap = new HashMap<>();
public static Shape getCircle(String color) {
Circle circle = (Circle) circleMap.get(color);
if (circle == null) {
circle = new Circle(color);
circleMap.put(color, circle);
System.out.println("Creating circle. Color: " + color);
}
return circle;
}
}
内容来自