【设计模式】《Java 设计模式魔法:解锁高效编程的秘密武器》
标题:《Java 设计模式奇幻之旅:解锁高效编程的魔法钥匙》
摘要: 本文将深入探讨 Java 中的十种设计模式,包括单例模式、工厂方法模式、抽象工厂模式…迭代器模式、组合模式、模板方法模式等。通过详细的解释、生动有趣的例子以及可运行的 Java 代码,帮助读者理解这些设计模式的核心思想和应用场景。读者将从中获得提升代码质量、增强可维护性和可扩展性的宝贵知识,开启高效编程的奇幻之旅。
关键词:Java 设计模式、单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、外观模式、代理模式、观察者模式、迭代器模式、组合模式、模板方法模式、命令模式、策略模式、状态模式、备忘录模式、中介者模式、责任链模式、访问者模式
一、单例模式(Singleton)
- 核心思想:确保一个类只有一个实例,并提供一个全局访问点。
- 例子:想象一个公司只有一个 CEO。无论在公司的哪个部门,当需要找 CEO 做决策时,都能通过一个特定的途径找到同一个 CEO,而不是有多个不同的“CEO”。
- Java 代码:
class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
二、工厂方法模式(Factory Method)
- 核心思想:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。
- 例子:比如有一个汽车工厂,工厂有一个生产汽车的接口。不同的分厂可以根据需求生产不同类型的汽车,如轿车分厂生产轿车,SUV 分厂生产 SUV。
- Java 代码:
interface Car {
void drive();
}
class Sedan implements Car {
@Override
public void drive() {
System.out.println("Driving Sedan.");
}
}
class SUV implements Car {
@Override
public void drive() {
System.out.println("Driving SUV.");
}
}
abstract class CarFactory {
public abstract Car createCar();
}
class SedanFactory extends CarFactory {
@Override
public Car createCar() {
return new Sedan();
}
}
class SUVFactory extends CarFactory {
@Override
public Car createCar() {
return new SUV();
}
}
三、抽象工厂模式(Abstract Factory)
- 核心思想:创建一个系列相关的或依赖对象的接口,而不需要明确指定它们具体的类。
- 例子:假设你在装修房子,有不同的装修风格套餐,比如现代风格套餐包含现代风格的沙发、餐桌等家具;欧式风格套餐包含欧式风格的家具。抽象工厂就像是提供不同风格套餐的装修公司。
- Java 代码:
interface Furniture {
void display();
}
class ModernSofa implements Furniture {
@Override
public void display() {
System.out.println("Modern Sofa.");
}
}
class ModernTable implements Furniture {
@Override
public void display() {
System.out.println("Modern Table.");
}
}
class EuropeanSofa implements Furniture {
@Override
public void display() {
System.out.println("European Sofa.");
}
}
class EuropeanTable implements Furniture {
@Override
public void display() {
System.out.println("European Table.");
}
}
interface FurnitureFactory {
Furniture createSofa();
Furniture createTable();
}
class ModernFurnitureFactory implements FurnitureFactory {
@Override
public Furniture createSofa() {
return new ModernSofa();
}
@Override
public Furniture createTable() {
return new ModernTable();
}
}
class EuropeanFurnitureFactory implements FurnitureFactory {
@Override
public Furniture createSofa() {
return new EuropeanSofa();
}
@Override
public Furniture createTable() {
return new EuropeanTable();
}
}
四、建造者模式(Builder)
- 核心思想:允许通过指定复杂对象的类型和内容逐步构建对象,以避免使用多个构造函数或设置器。
- 例子:比如建造一个房子,有不同的部分如地基、墙壁、屋顶等。建造者模式可以让你逐步构建房子,先打地基,然后砌墙,最后安装屋顶,而不是一次性用一个复杂的构造函数来创建房子。
- Java 代码:
class House {
private String foundation;
private String walls;
private String roof;
public void setFoundation(String foundation) {
this.foundation = foundation;
}
public void setWalls(String walls) {
this.walls = walls;
}
public void setRoof(String roof) {
this.roof = roof;
}
@Override
public String toString() {
return "House{" +
"foundation='" + foundation + '\'' +
", walls='" + walls + '\'' +
", roof='" + roof + '\'' +
'}';
}
}
interface HouseBuilder {
void buildFoundation();
void buildWalls();
void buildRoof();
House getHouse();
}
class ConcreteHouseBuilder implements HouseBuilder {
private House house = new House();
@Override
public void buildFoundation() {
house.setFoundation("Strong foundation");
}
@Override
public void buildWalls() {
house.setWalls("Brick walls");
}
@Override
public void buildRoof() {
house.setRoof("Tiled roof");
}
@Override
public House getHouse() {
return house;
}
}
五、原型模式(Prototype)
- 核心思想:通过复制现有的实例创建新的实例,而不是通过新建。
- 例子:想象你有一个复杂的图形设计软件,你已经花了很多时间设计了一个漂亮的图形。现在你想在这个基础上做一些小的修改来创建一个新的图形,而不是从头开始设计。原型模式就可以让你复制这个现有的图形,然后进行修改。
- Java 代码:
class Graphic {
private String color;
private int size;
public Graphic(String color, int size) {
this.color = color;
this.size = size;
}
public Graphic clone() {
return new Graphic(this.color, this.size);
}
@Override
public String toString() {
return "Graphic{" +
"color='" + color + '\'' +
", size=" + size +
'}';
}
}
六、适配器模式(Adapter)
- 核心思想:允许不兼容的接口一起工作,通过一个转换接口的类来适配它们。
- 例子:比如你有一个旧的手机充电器,它的接口和你的新手机不兼容。这时你可以使用一个适配器,将旧充电器的接口转换为新手机可以使用的接口。
- Java 代码:
interface Target {
void charge();
}
class NewPhone {
public void chargeWithNewInterface() {
System.out.println("Charging with new interface.");
}
}
class Adapter implements Target {
private NewPhone newPhone;
public Adapter(NewPhone newPhone) {
this.newPhone = newPhone;
}
@Override
public void charge() {
newPhone.chargeWithNewInterface();
}
}
七、装饰器模式(Decorator)
- 核心思想:动态地给一个对象添加额外的职责,而不改变其结构。
- 例子:想象你有一杯咖啡,你可以通过添加糖、牛奶等装饰来改变咖啡的味道,而不需要改变咖啡本身的结构。
- Java 代码:
interface Coffee {
double getCost();
String getDescription();
}
class SimpleCoffee implements Coffee {
@Override
public double getCost() {
return 2.0;
}
@Override
public String getDescription() {
return "Simple coffee";
}
}
class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) {
this.coffee = coffee;
}
@Override
public double getCost() {
return coffee.getCost();
}
@Override
public String getDescription() {
return coffee.getDescription();
}
}
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.5;
}
@Override
public String getDescription() {
return super.getDescription() + ", with milk";
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double getCost() {
return super.getCost() + 0.2;
}
@Override
public String getDescription() {
return super.getDescription() + ", with sugar";
}
}
八、外观模式(Facade)
- 核心思想:提供一个统一的高层接口,用于访问子系统中的一群接口。
- 例子:想象你有一个复杂的音响系统,有很多按钮和设置。外观模式可以提供一个简单的遥控器,让你可以通过几个简单的按钮来控制整个音响系统,而不需要直接操作每个组件。
- Java 代码:
class Amplifier {
public void on() {
System.out.println("Amplifier on.");
}
public void off() {
System.out.println("Amplifier off.");
}
}
class Tuner {
public void tune() {
System.out.println("Tuner tuned.");
}
}
class DvdPlayer {
public void play() {
System.out.println("DVD player playing.");
}
public void stop() {
System.out.println("DVD player stopped.");
}
}
class Projector {
public void on() {
System.out.println("Projector on.");
}
public void off() {
System.out.println("Projector off.");
}
}
class Screen {
public void up() {
System.out.println("Screen up.");
}
public void down() {
System.out.println("Screen down.");
}
}
class HomeTheaterFacade {
private Amplifier amplifier;
private Tuner tuner;
private DvdPlayer dvdPlayer;
private Projector projector;
private Screen screen;
public HomeTheaterFacade() {
amplifier = new Amplifier();
tuner = new Tuner();
dvdPlayer = new DvdPlayer();
projector = new Projector();
screen = new Screen();
}
public void watchMovie() {
amplifier.on();
tuner.tune();
dvdPlayer.play();
projector.on();
screen.down();
}
public void endMovie() {
amplifier.off();
tuner.off();
dvdPlayer.stop();
projector.off();
screen.up();
}
}
九、代理模式(Proxy)
- 核心思想:为其他对象提供一个代替或占位符,以控制对它的访问。
- 例子:想象你是一个明星的经纪人。当有人想要联系明星时,他们需要通过你来安排。你就是明星的代理,控制着对明星的访问。
- Java 代码:
interface Star {
void act();
}
class RealStar implements Star {
@Override
public void act() {
System.out.println("Star is acting.");
}
}
class StarProxy implements Star {
private RealStar realStar;
public StarProxy() {
realStar = new RealStar();
}
@Override
public void act() {
System.out.println("Checking if star is available...");
realStar.act();
}
}
十、观察者模式(Observer)
- 核心思想:对象间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
- 例子:比如你在一个新闻网站上订阅了一些新闻频道。当有新的新闻发布时,新闻网站会通知所有订阅了该频道的用户。用户就是观察者,新闻网站就是被观察的对象。
- Java 代码:
interface Observer {
void update();
}
class NewsWebsite implements Observer {
private String news;
@Override
public void update() {
System.out.println("News received: " + news);
}
public void setNews(String news) {
this.news = news;
}
}
class NewsPublisher {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void publishNews(String news) {
System.out.println("New news published: " + news);
for (Observer observer : observers) {
observer.update();
}
}
}
十一、迭代器模式(Iterator)
- 核心思想:顺序访问一个聚合对象中的各个元素,不暴露其内部的表示。
- 例子:想象你有一个装满玩具的箱子,你想一个一个地拿出玩具来玩,但你不需要知道箱子是如何存储玩具的。迭代器就像是你的小手,能够逐个取出玩具,而不关心箱子的内部结构。
- Java 代码:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Toy {
private String name;
public Toy(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class ToyBox implements Iterable<Toy> {
private List<Toy> toys = new ArrayList<>();
public void addToy(Toy toy) {
toys.add(toy);
}
@Override
public Iterator<Toy> iterator() {
return toys.iterator();
}
}
十二、组合模式(Composite)
- 核心思想:将对象组合成树形结构以表示“部分-整体”的层次结构。
- 例子:想象一个公司的组织结构,有部门和员工。部门可以包含子部门和员工,就像一棵树。组合模式可以让你统一处理部门和员工,无论是计算工资还是执行其他操作。
- Java 代码:
interface OrganizationComponent {
void displayInfo();
}
class Employee implements OrganizationComponent {
private String name;
public Employee(String name) {
this.name = name;
}
@Override
public void displayInfo() {
System.out.println("Employee: " + name);
}
}
class Department implements OrganizationComponent {
private String name;
private List<OrganizationComponent> components = new ArrayList<>();
public Department(String name) {
this.name = name;
}
public void addComponent(OrganizationComponent component) {
components.add(component);
}
@Override
public void displayInfo() {
System.out.println("Department: " + name);
for (OrganizationComponent component : components) {
component.displayInfo();
}
}
}
十三、模板方法模式(Template Method)
- 核心思想:在一个方法中定义算法的骨架,将一些步骤的执行延迟到子类中。
- 例子:比如做蛋糕,有一个基本的流程是准备材料、搅拌、烘烤、装饰。不同类型的蛋糕在某些步骤上可能会有所不同,比如巧克力蛋糕和水果蛋糕的装饰方式不同。模板方法模式就可以定义这个做蛋糕的基本流程,而具体的装饰步骤由子类实现。
- Java 代码:
abstract class CakeMaking {
public final void makeCake() {
prepareIngredients();
mixIngredients();
bake();
decorate();
}
protected abstract void decorate();
protected void prepareIngredients() {
System.out.println("Preparing common ingredients.");
}
protected void mixIngredients() {
System.out.println("Mixing ingredients.");
}
protected void bake() {
System.out.println("Baking the cake.");
}
}
class ChocolateCake extends CakeMaking {
@Override
protected void decorate() {
System.out.println("Decorating with chocolate.");
}
}
class FruitCake extends CakeMaking {
@Override
protected void decorate() {
System.out.println("Decorating with fruits.");
}
}
十四、命令模式(Command)
- 核心思想:将请求或操作封装为一个对象,从而使用户可用不同的请求、队列或日志请求来参数化其他对象。
- 例子:想象你有一个遥控器,上面有不同的按钮,每个按钮代表一个命令,比如打开电视、切换频道等。命令模式可以将这些操作封装成一个个命令对象,当你按下按钮时,就执行相应的命令。
- Java 代码:
interface Command {
void execute();
}
class TurnOnTVCommand implements Command {
private TV tv;
public TurnOnTVCommand(TV tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turnOn();
}
}
class TV {
public void turnOn() {
System.out.println("TV is turned on.");
}
public void turnOff() {
System.out.println("TV is turned off.");
}
}
十五、策略模式(Strategy)
- 核心思想:定义一系列算法,把它们一个个封装起来,并使它们可互换。
- 例子:想象你要去旅行,可以选择不同的交通方式,比如坐飞机、坐火车、开车。策略模式可以让你根据不同的情况选择不同的交通方式,而不需要修改旅行的其他部分。
- Java 代码:
interface TravelStrategy {
void travel();
}
class FlyStrategy implements TravelStrategy {
@Override
public void travel() {
System.out.println("Traveling by air.");
}
}
class TrainStrategy implements TravelStrategy {
@Override
public void travel() {
System.out.println("Traveling by train.");
}
}
class DriveStrategy implements TravelStrategy {
@Override
public void travel() {
System.out.println("Traveling by car.");
}
}
class Traveler {
private TravelStrategy strategy;
public void setStrategy(TravelStrategy strategy) {
this.strategy = strategy;
}
public void travel() {
strategy.travel();
}
}
十六、状态模式(State)
- 核心思想:允许一个对象在其内部状态改变时改变它的行为,看起来好像改变了其类。
- 例子:想象一个手机,有不同的状态,比如开机状态、关机状态、飞行模式状态等。当手机处于不同状态时,它的行为也不同,比如在开机状态可以打电话、发短信,在关机状态则不能。状态模式可以让手机根据不同的状态自动切换行为。
- Java 代码:
interface PhoneState {
void handle();
}
class OnState implements PhoneState {
@Override
public void handle() {
System.out.println("Phone is on. You can make calls and send messages.");
}
}
class OffState implements PhoneState {
@Override
public void handle() {
System.out.println("Phone is off.");
}
}
class FlightModeState implements PhoneState {
@Override
public void handle() {
System.out.println("Phone is in flight mode. You can't make calls.");
}
}
class Phone {
private PhoneState state;
public Phone() {
state = new OffState();
}
public void setState(PhoneState state) {
this.state = state;
}
public void handleState() {
state.handle();
}
}
十七、备忘录模式(Memento)
- 核心思想:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
- 例子:想象你在玩一个游戏,你可以随时保存游戏进度。备忘录模式就可以让你把游戏当前的状态保存下来,比如角色的位置、生命值等,以便以后可以恢复到这个状态。
- Java 代码:
class GameState {
private int playerHealth;
private int playerPosition;
public GameState(int health, int position) {
playerHealth = health;
playerPosition = position;
}
public int getPlayerHealth() {
return playerHealth;
}
public int getPlayerPosition() {
return playerPosition;
}
}
class Game {
private int playerHealth = 100;
private int playerPosition = 0;
public GameState saveState() {
return new GameState(playerHealth, playerPosition);
}
public void restoreState(GameState state) {
playerHealth = state.getPlayerHealth();
playerPosition = state.getPlayerPosition();
}
public void takeDamage(int damage) {
playerHealth -= damage;
}
public void move(int steps) {
playerPosition += steps;
}
}
十八、中介者模式(Mediator)
- 核心思想:用一个中介对象来封装一系列的对象交互,使各对象不需要显示地相互引用。
- 例子:想象一个办公室里有很多员工,他们需要相互沟通和协作。如果没有中介者,每个员工都需要知道其他所有员工的联系方式,这会很混乱。中介者模式可以引入一个经理作为中介者,员工只需要和经理沟通,经理负责协调员工之间的工作。
- Java 代码:
interface Colleague {
void send(String message);
void receive(String message);
}
class Employee implements Colleague {
private String name;
private Mediator mediator;
public Employee(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
@Override
public void send(String message) {
mediator.sendMessage(message, this);
}
@Override
public void receive(String message) {
System.out.println(name + " received: " + message);
}
}
class Mediator {
private List<Colleague> colleagues = new ArrayList<>();
public void addColleague(Colleague colleague) {
colleagues.add(colleague);
}
public void sendMessage(String message, Colleague sender) {
for (Colleague colleague : colleagues) {
if (colleague!= sender) {
colleague.receive(message);
}
}
}
}
十九、责任链模式(Chain of Responsibility)
- 核心思想:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
- 例子:想象你在一个公司里提交一份报销申请。申请会经过不同的审批人,比如部门经理、财务主管等。如果一个审批人不能批准,申请会传递给下一个审批人。责任链模式可以实现这样的审批流程。
- Java 代码:
interface Approver {
void setNextApprover(Approver approver);
void approveRequest(int amount);
}
class Manager implements Approver {
private Approver nextApprover;
@Override
public void setNextApprover(Approver approver) {
nextApprover = approver;
}
@Override
public void approveRequest(int amount) {
if (amount <= 1000) {
System.out.println("Manager approved request for $" + amount);
} else if (nextApprover!= null) {
nextApprover.approveRequest(amount);
} else {
System.out.println("Request cannot be approved.");
}
}
}
class FinanceDirector implements Approver {
private Approver nextApprover;
@Override
public void setNextApprover(Approver approver) {
nextApprover = approver;
}
@Override
public void approveRequest(int amount) {
if (amount <= 5000) {
System.out.println("Finance Director approved request for $" + amount);
} else if (nextApprover!= null) {
nextApprover.approveRequest(amount);
} else {
System.out.println("Request cannot be approved.");
}
}
}
二十、访问者模式(Visitor)
- 核心思想:为一个对象结构(如组合结构)增加新能力,通过访问者对象来实现,而不是修改现有类。
- 例子:想象你有一个动物园,里面有不同种类的动物。你想统计不同种类动物的数量,或者给不同种类的动物喂食。访问者模式可以让你定义一个访问者对象,它可以访问动物园中的每个动物,并执行特定的操作,而不需要修改动物类。
- Java 代码:
interface Animal {
void accept(Visitor visitor);
}
class Lion implements Animal {
@Override
public void accept(Visitor visitor) {
visitor.visitLion(this);
}
}
class Tiger implements Animal {
@Override
public void accept(Visitor visitor) {
visitor.visitTiger(this);
}
}
interface Visitor {
void visitLion(Lion lion);
void visitTiger(Tiger tiger);
}
class AnimalCounter implements Visitor {
private int lionCount;
private int tigerCount;
@Override
public void visitLion(Lion lion) {
lionCount++;
}
@Override
public void visitTiger(Tiger tiger) {
tigerCount++;
}
public void displayCounts() {
System.out.println("Number of lions: " + lionCount);
System.out.println("Number of tigers: " + tigerCount);
}
}
嘿,小伙伴们!这些设计模式是不是超级酷炫呢?快来评论区分享你在编程中使用设计模式的奇妙经历吧!让我们一起在 Java 设计模式的海洋中畅游,创造出更加精彩的代码!😎