在Java面试中,设计模式是一个非常重要的考察点,面试官通常希望通过设计模式的问题来评估候选人对软件设计原则和最佳实践的理解程度。以下是一些常见的面试要点,以及相关的详细说明和案例:
1. 设计模式的基本概念
面试官可能会询问设计模式的基本概念,如:
案例: 设计模式是针对软件设计中常见问题的通用、可重用的解决方案。例如,单例模式(Singleton)是一种创建型模式,它确保一个类只有一个实例,并提供一个全局访问点。
2. 创建型模式
-
单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点。
案例:
public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
-
工厂模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪个类。
案例:
public interface VehicleFactory { Vehicle createVehicle(); } public class CarFactory implements VehicleFactory { public Vehicle createVehicle() { return new Car(); } }
-
抽象工厂模式(Abstract Factory):提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
案例:
public interface AbstractFactory { Vehicle createVehicle(); Engine createEngine(); } public class CarFactory implements AbstractFactory { public Vehicle createVehicle() { return new Car(); } public Engine createEngine() { return new CarEngine(); } }
3. 结构型模式
-
适配器模式(Adapter):允许将一个类的接口转换成客户期望的另一个接口。
案例:
public interface Target { void request(); } public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; } @Override public void request() { adaptee.specificRequest(); } }
-
装饰器模式(Decorator):动态地给一个对象添加一些额外的职责,而不改变其接口。
案例:
public interface Component { void operation(); } public class ConcreteComponent implements Component { @Override public void operation() { System.out.println("ConcreteComponent operation"); } } public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } @Override public void operation() { super.operation(); addAdditionalBehavior(); } private void addAdditionalBehavior() { System.out.println("Added behavior by ConcreteDecoratorA"); } }
-
代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。
案例:
public interface Image { void display(); } public class RealImage implements Image { private String filename; public RealImage(String filename) { this.filename = filename; loadImageFromDisk(); } private void loadImageFromDisk() { System.out.println("Loading " + filename); } @Override public void display() { System.out.println("Displaying " + filename); } } public class ImageProxy implements Image { private RealImage realImage; private String filename; public ImageProxy(String filename) { this.filename = filename; } @Override public void display() { if (realImage == null) { realImage = new RealImage(filename); } realImage.display(); } }
4. 行为型模式
行为型模式关注对象之间的通信,主要有以下几种:
-
策略模式(Strategy):定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换。
案例:
public interface Strategy { int doOperation(int num1, int num2); } public class OperationAdd implements Strategy { @Override public int doOperation(int num1, int num2) { return num1 + num2; } } public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public int executeStrategy(int num1, int num2) { return strategy.doOperation(num1, num2); } }
-
观察者模式(Observer):当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。
案例:
public interface Observer { void update(); } public class Subject { private List<Observer> observers = new ArrayList<>(); private int state; public void attach(Observer observer) { observers.add(observer); } public void setState(int state) { this.state = state; notifyAllObservers(); } public int getState() { return state; } private void notifyAllObservers() { for (Observer observer : observers) { observer.update(); } } } public class ConcreteObserver implements Observer { private Subject subject; public ConcreteObserver(Subject subject) { this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println("Subject state changed to: " + subject.getState()); } }
-
命令模式(Command):将请求封装成对象,从而可以使用不同的请求、队列或日志请求来参数化其他对象。
案例:
public interface Command { void execute(); } public class Light { public void turnOn() { System.out.println("Light is on"); } public void turnOff() { System.out.println("Light is off"); } } public class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.turnOn(); } } public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } }
5. 实际应用
在面试中,面试官可能会询问设计模式在实际项目中的应用,例如:
案例: 在一个电商平台中,使用了工厂模式来创建不同类型的订单处理类。这样,当需要增加新的订单类型时,只需要增加一个新的工厂类和相应的订单处理类,而不需要修改现有的代码结构。这种做法使得代码更加模块化,易于扩展和维护。
总结
设计模式的面试涉及对模式的深入理解、实际应用以及对代码质量和设计原则的掌握。通过案例和实际项目经验,候选人可以更好地展示自己在这方面的能力。