标题:《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 {@Overridepublic void drive() {System.out.println("Driving Sedan.");}
}class SUV implements Car {@Overridepublic void drive() {System.out.println("Driving SUV.");}
}abstract class CarFactory {public abstract Car createCar();
}class SedanFactory extends CarFactory {@Overridepublic Car createCar() {return new Sedan();}
}class SUVFactory extends CarFactory {@Overridepublic Car createCar() {return new SUV();}
}
三、抽象工厂模式(Abstract Factory)
- 核心思想:创建一个系列相关的或依赖对象的接口,而不需要明确指定它们具体的类。
- 例子:假设你在装修房子,有不同的装修风格套餐,比如现代风格套餐包含现代风格的沙发、餐桌等家具;欧式风格套餐包含欧式风格的家具。抽象工厂就像是提供不同风格套餐的装修公司。
- Java 代码:
interface Furniture {void display();
}class ModernSofa implements Furniture {@Overridepublic void display() {System.out.println("Modern Sofa.");}
}class ModernTable implements Furniture {@Overridepublic void display() {System.out.println("Modern Table.");}
}class EuropeanSofa implements Furniture {@Overridepublic void display() {System.out.println("European Sofa.");}
}class EuropeanTable implements Furniture {@Overridepublic void display() {System.out.println("European Table.");}
}interface FurnitureFactory {Furniture createSofa();Furniture createTable();
}class ModernFurnitureFactory implements FurnitureFactory {@Overridepublic Furniture createSofa() {return new ModernSofa();}@Overridepublic Furniture createTable() {return new ModernTable();}
}class EuropeanFurnitureFactory implements FurnitureFactory {@Overridepublic Furniture createSofa() {return new EuropeanSofa();}@Overridepublic 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;}@Overridepublic 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();@Overridepublic void buildFoundation() {house.setFoundation("Strong foundation");}@Overridepublic void buildWalls() {house.setWalls("Brick walls");}@Overridepublic void buildRoof() {house.setRoof("Tiled roof");}@Overridepublic 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);}@Overridepublic 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;}@Overridepublic void charge() {newPhone.chargeWithNewInterface();}
}
七、装饰器模式(Decorator)
- 核心思想:动态地给一个对象添加额外的职责,而不改变其结构。
- 例子:想象你有一杯咖啡,你可以通过添加糖、牛奶等装饰来改变咖啡的味道,而不需要改变咖啡本身的结构。
- Java 代码:
interface Coffee {double getCost();String getDescription();
}class SimpleCoffee implements Coffee {@Overridepublic double getCost() {return 2.0;}@Overridepublic String getDescription() {return "Simple coffee";}
}class CoffeeDecorator implements Coffee {protected Coffee coffee;public CoffeeDecorator(Coffee coffee) {this.coffee = coffee;}@Overridepublic double getCost() {return coffee.getCost();}@Overridepublic String getDescription() {return coffee.getDescription();}
}class MilkDecorator extends CoffeeDecorator {public MilkDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 0.5;}@Overridepublic String getDescription() {return super.getDescription() + ", with milk";}
}class SugarDecorator extends CoffeeDecorator {public SugarDecorator(Coffee coffee) {super(coffee);}@Overridepublic double getCost() {return super.getCost() + 0.2;}@Overridepublic 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 {@Overridepublic void act() {System.out.println("Star is acting.");}
}class StarProxy implements Star {private RealStar realStar;public StarProxy() {realStar = new RealStar();}@Overridepublic 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;@Overridepublic 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);}@Overridepublic 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;}@Overridepublic 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);}@Overridepublic 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 {@Overrideprotected void decorate() {System.out.println("Decorating with chocolate.");}
}class FruitCake extends CakeMaking {@Overrideprotected 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;}@Overridepublic 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 {@Overridepublic void travel() {System.out.println("Traveling by air.");}
}class TrainStrategy implements TravelStrategy {@Overridepublic void travel() {System.out.println("Traveling by train.");}
}class DriveStrategy implements TravelStrategy {@Overridepublic 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 {@Overridepublic void handle() {System.out.println("Phone is on. You can make calls and send messages.");}
}class OffState implements PhoneState {@Overridepublic void handle() {System.out.println("Phone is off.");}
}class FlightModeState implements PhoneState {@Overridepublic 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;}@Overridepublic void send(String message) {mediator.sendMessage(message, this);}@Overridepublic 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;@Overridepublic void setNextApprover(Approver approver) {nextApprover = approver;}@Overridepublic 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;@Overridepublic void setNextApprover(Approver approver) {nextApprover = approver;}@Overridepublic 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 {@Overridepublic void accept(Visitor visitor) {visitor.visitLion(this);}
}class Tiger implements Animal {@Overridepublic 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;@Overridepublic void visitLion(Lion lion) {lionCount++;}@Overridepublic void visitTiger(Tiger tiger) {tigerCount++;}public void displayCounts() {System.out.println("Number of lions: " + lionCount);System.out.println("Number of tigers: " + tigerCount);}
}
嘿,小伙伴们!这些设计模式是不是超级酷炫呢?快来评论区分享你在编程中使用设计模式的奇妙经历吧!让我们一起在 Java 设计模式的海洋中畅游,创造出更加精彩的代码!😎