構造パターン
システム設計におけるオブジェクトの関係と編成における一般的な問題を解決するために使用されます。これらのパターンは、さまざまなオブジェクト間のインターフェイス、関連付け、集約、継承関係を定義することにより、より柔軟で再利用可能で保守可能なソフトウェア システムを構築するのに役立ちます。
アダプターモード
機能: インターフェースの互換性がないために本来連携できないクラスを連携させます。
アダプター パターンの中心となるアイデアは、互換性のない 2 つのインターフェイス間のブリッジとして機能するアダプターを導入することです。アダプターは、クライアントが期待するターゲット インターフェイスを実装しており、互換性のないインターフェイスへの内部参照が含まれています。
クラスアダプターパターン
クラス アダプター パターンは、多重継承を通じて 1 つのクラスを別のインターフェイスに適応させます。アダプタクラスは、ターゲットインタフェースを継承すると同時に適応クラスも継承することにより、ターゲットインタフェースと適応クラスとを連携させる。アダプター クラスがターゲット インターフェイス メソッドを実装する場合、アダプター クラスは適応されたクラスのメソッドを呼び出して適応を実装します。
public interface Target {
void request();
}
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: specificRequest");
}
}
// 创建适配器,同时继承被适配者的类,又实现目标接口,使二者建立联系
public class Adapter extends Adaptee implements Target {
@Override
public void request() {
specificRequest();
}
}
// 用户端使用适配器
public class Client {
public static void main(String[] args) {
Target target = new Adapter();
// request()方法调用了Adaptee类的specificRequest()方法
// 从而来实现适配。
target.request();
}
}
オブジェクトアダプターパターン
オブジェクト アダプター パターンは、合成を通じて 1 つのクラスを別のインターフェイスに適応させます。アダプター クラスには、適応されたクラスのインスタンスが含まれており、適応は、適応されたクラスのメソッドを呼び出すことによって実現されます。
public interface Target {
void request();
}
public class Adaptee {
public void specificRequest() {
System.out.println("Adaptee: specificRequest");
}
}
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
// 调用适配器
public class Client {
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
Target target = new Adapter(adaptee);
// 调用适配后的接口方法
target.request();
}
}
デコレータパターン
機能: 既存のオブジェクトの構造を変更せずに、新しい機能を追加できます。
原則: 装飾クラスは、クラス メソッド シグネチャの整合性を維持しながら、元のクラスをラップし、追加の機能を提供するために作成されます。
// 抽象组件
public interface Component {
void operation();
}
// 具体组件
public class ConcreteComponent implements Component {
public void operation() {
System.out.println("执行原始操作");
}
}
// 抽象装饰器
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
// 具体装饰器
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
// 增加新的行为
addBehavior();
}
private void addBehavior() {
System.out.println("执行额外行为");
}
}
// 使用装饰器模式
public class Main {
public static void main(String[] args) {
Component component = new ConcreteComponent();
Component decoratedComponent = new ConcreteDecorator(component);
decoratedComponent.operation();
}
}
プロキシモード
機能: プロキシ オブジェクトを通じて実際のオブジェクトへのアクセスを制御します。
原則: コアはプロキシ クラスであり、実際のオブジェクトと同じインターフェイスを実装し、実際のオブジェクトへの参照を保持します。プロキシ クラスは、呼び出し時に実際のオブジェクトを管理および制御する責任を負い、実際のオブジェクトのメソッドの呼び出しの前後に追加のロジックを追加できます。
// 抽象主题接口
interface Subject {
void request();
}
// 真实主题
class RealSubject implements Subject {
public void request() {
System.out.println("执行真实主题的请求");
}
}
// 代理类
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy() {
this.realSubject = new RealSubject();
}
public void request() {
System.out.println("代理类处理请求");
this.realSubject.request();
}
}
// 使用代理模式
public class Client {
public static void main(String[] args) {
Subject proxy = new Proxy();
proxy.request();
}
}
外観モード
機能: 複雑なサブシステムにシンプルで統一されたインターフェイスを提供し、クライアントがサブシステムとより便利に対話できるようにすると同時に、サブシステムをクライアントから切り離します。
原則: 外観クラスを導入することにより、関連するサブシステム インターフェイスのセットがカプセル化され、クライアント用に高レベルのインターフェイスが提供されます。クライアントは外観クラスと対話するだけでよく、サブシステムの複数のクラスと直接対話する必要がないため、クライアントの呼び出し操作が簡素化されます。
// 子系统类
class MusicPlayer {
public void playSong(String song) {
System.out.println("播放音乐:" + song);
}
}
class VideoPlayer {
public void playVideo(String video) {
System.out.println("播放视频:" + video);
}
}
class SubtitleDisplay {
public void displaySubtitle(String video) {
System.out.println("显示字幕:" + video);
}
}
// 外观类
class AudioPlayer {
private MusicPlayer musicPlayer;
private VideoPlayer videoPlayer;
private SubtitleDisplay subtitleDisplay;
public AudioPlayer() {
musicPlayer = new MusicPlayer();
videoPlayer = new VideoPlayer();
subtitleDisplay = new SubtitleDisplay();
}
// 对外提供的高层次接口
public void playMusic(String song) {
musicPlayer.playSong(song);
}
public void playVideo(String video) {
videoPlayer.playVideo(video);
subtitleDisplay.displaySubtitle(video);
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
// 直接通过外观调用
audioPlayer.playMusic("Yesterday");
audioPlayer.playVideo("Avatar");
}
}
ブリッジモード
機能: 抽象部分を実装部分から分離し、独立して変更できるようにします。
原則: 抽象部分と実装部分を分離するブリッジ インターフェイスを作成します。抽象部分はブリッジ インターフェイスを介して実装部分を呼び出します。これにより、抽象化と実装の分離が実現され、それらを独立して拡張および変更できるようになります。
// 抽象部分
abstract class Shape {
protected DrawingAPI drawingAPI;
protected Shape(DrawingAPI drawingAPI) {
this.drawingAPI = drawingAPI;
}
public abstract void draw();
}
// 扩展抽象部分
class LineShape extends Shape {
public LineShape(DrawingAPI drawingAPI) {
super(drawingAPI);
}
public void draw() {
System.out.println("绘制直线");
drawingAPI.draw();
}
}
class CircleShape extends Shape {
public CircleShape(DrawingAPI drawingAPI) {
super(drawingAPI);
}
public void draw() {
System.out.println("绘制圆形");
drawingAPI.draw();
}
}
// 实现部分
interface DrawingAPI {
void draw();
}
// 具体实现部分
class DirectXAPI implements DrawingAPI {
public void draw() {
System.out.println("使用DirectX绘图API");
}
}
class OpenGLAPI implements DrawingAPI {
public void draw() {
System.out.println("使用OpenGL绘图API");
}
}
// 使用桥接模式代码
public class Client {
public static void main(String[] args) {
DrawingAPI directx = new DirectXAPI();
DrawingAPI opengl = new OpenGLAPI();
Shape lineShape = new LineShape(directx);
lineShape.draw();
Shape circleShape = new CircleShape(opengl);
circleShape.draw();
}
}
コンビネーションモード
機能: 結合モードにより、クライアントは単一オブジェクトと結合オブジェクトを均一に扱うことができるため、ユーザーは単一オブジェクトと結合オブジェクトを一貫して使用できるため、オブジェクト ツリー構造の使用の複雑さが軽減されます。
原則: コンポーネント + リーフ コンポーネント + コンテナ コンポーネント
// 实现一个文件系统的树形结构,包括文件和文件夹两种类型的节点:
// 组件接口
interface FileSystemComponent {
void printStructure();
}
// 叶子组件:文件
class File implements FileSystemComponent {
private String name;
public File(String name) {
this.name = name;
}
public void printStructure() {
System.out.println("文件: " + name);
}
}
// 容器组件:文件夹
class Folder implements FileSystemComponent {
private String name;
private List<FileSystemComponent> components;
public Folder(String name) {
this.name = name;
components = new ArrayList<>();
}
public void addComponent(FileSystemComponent component) {
components.add(component);
}
public void removeComponent(FileSystemComponent component) {
components.remove(component);
}
public void printStructure() {
System.out.println("文件夹: " + name);
for (FileSystemComponent component : components) {
component.printStructure();
}
}
}
// 使用组合模式
public class Client {
public static void main(String[] args) {
FileSystemComponent file1 = new File("file1.txt");
FileSystemComponent file2 = new File("file2.txt");
FileSystemComponent file3 = new File("file3.txt");
FileSystemComponent folder1 = new Folder("folder1");
folder1.addComponent(file1);
folder1.addComponent(file2);
FileSystemComponent folder2 = new Folder("folder2");
folder2.addComponent(file3);
FileSystemComponent root = new Folder("root");
root.addComponent(folder1);
root.addComponent(folder2);
root.printStructure();
}
}
フライウェイトモード
機能: オブジェクトを共有することでシステムのパフォーマンスを向上させ、メモリ消費を削減します。
原則: オブジェクトを共有可能な部分 (内部状態) と共有不可能な部分 (外部状態) に分割し、内部状態を共有することでオブジェクトの作成と保存を削減します。
// 抽象享元接口
interface ChessPiece {
void draw(int x, int y);
}
// 具体享元类:白色棋子
class WhiteChessPiece implements ChessPiece {
private String color;
public WhiteChessPiece() {
this.color = "白色";
}
public void draw(int x, int y) {
System.out.println(color + "棋子,位置:(" + x + ", " + y + ")");
}
}
// 具体享元类:黑色棋子
class BlackChessPiece implements ChessPiece {
private String color;
public BlackChessPiece() {
this.color = "黑色";
}
public void draw(int x, int y) {
System.out.println(color + "棋子,位置:(" + x + ", " + y + ")");
}
}
// 享元工厂类
class ChessPieceFactory {
private HashMap<String, ChessPiece> chessPieces;
public ChessPieceFactory() {
chessPieces = new HashMap<>();
}
public ChessPiece getChessPiece(String color) {
if (chessPieces.containsKey(color)) {
return chessPieces.get(color);
} else {
ChessPiece chessPiece;
if (color.equals("白色")) {
chessPiece = new WhiteChessPiece();
} else {
chessPiece = new BlackChessPiece();
}
chessPieces.put(color, chessPiece);
return chessPiece;
}
}
}
// 使用享元模式
public class Client {
public static void main(String[] args) {
ChessPieceFactory factory = new ChessPieceFactory();
ChessPiece whitePiece1 = factory.getChessPiece("白色");
whitePiece1.draw(0, 0);
ChessPiece blackPiece1 = factory.getChessPiece("黑色");
blackPiece1.draw(0, 1);
ChessPiece whitePiece2 = factory.getChessPiece("白色");
whitePiece2.draw(1, 0);
// 输出结果:
// 白色棋子,位置:(0, 0)
// 黑色棋子,位置:(0, 1)
// 白色棋子,位置:(1, 0)
}
}