2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

GoFデザインパターンの一つで,構造に関するパターンである
Compositeパターンについて扱いたいと思います.

Compositeパターンとは?

Compositeパターンとは,オブジェクトを階層構造で表現し、個々のオブジェクトとそのグループを同一視できるようにするデザインパターンです.

...つまり,どういったことができるようになるのでしょう???

ポイントは同一視というワードです.

同一視することができるというのは,
階層構造のものに一つのインタフェースを実装することで,
違うクラスであっても同じオブジェクトとして扱うことが可能になる
ということです.

...言葉ではよくわからないので例を見ていきましょう.

Compositeパターンの実装

図形を例にした時の,Compositeパターンの構造は以下のようになります.

CompositeShapeがShapeのインスタンスのリストを管理します.

そして,CompsiteShapeのdraw()が呼び出されると,リストに登録されているShapeのインスタンスにメソッドの処理を委譲します.

つまり,CompsiteShapeを一つのShapeと見なすことができ,CompositeShapeだけで様々な図形を描くことができます.

これは,CompositeShapeとShapeを同一視することができるというのを表しています.
スクリーンショット 2025-01-03 040039.png

以下は具体的なソースコードと実装例になります.

  • App.java
App.java
public class App {
    public static void main(String[] args) {
        
        Shape circle = new Circle();
        Shape square = new Square();
        
        CompositeShape compositeShape = new CompositeShape();
        compositeShape.add(circle);
        compositeShape.add(square);
        
        CompositeShape nestedComposite = new CompositeShape();
        nestedComposite.add(compositeShape);
        nestedComposite.add(new Circle());

        System.out.println("Drawing individual shapes:");
        circle.draw();
        square.draw();

        System.out.println("\nDrawing composite shape:");
        compositeShape.draw();

        System.out.println("\nDrawing nested composite shape:");
        nestedComposite.draw();
    }
}
  • Shape.java
Shape.java
interface Shape {
    void draw();
}
  • Circle.java
Circle.java
class Circle implements Shape{
    @Override
    public void draw() {
        System.out.println("Drawing a Circle");
    }
}
  • Square.java
Square.java
class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Drawing a Square");
    }
}
  • CompositeShape.java
CompositeShape.java
import java.util.ArrayList;
import java.util.List;

class CompositeShape implements Shape {
    private List<Shape> shapes = new ArrayList<>();

    public void add(Shape shape) {
        shapes.add(shape);
    }

    public void remove(Shape shape) {
        shapes.remove(shape);
    }

    @Override
    public void draw() {
        System.out.println("Drawing a CompositeShape with the following shapes:");
        for (Shape shape : shapes) {
            shape.draw();
        }
    }
}
実装例
Drawing individual shapes:
Drawing a Circle
Drawing a Square

Drawing composite shape:
Drawing a CompositeShape with the following shapes:
Drawing a Circle
Drawing a Square

Drawing nested composite shape:
Drawing a CompositeShape with the following shapes:
Drawing a CompositeShape with the following shapes:
Drawing a Circle
Drawing a Square
Drawing a Circle

で、何が嬉しいの?

同一視することができるといいましたが,
どういったことがメリットとして挙げられるのでしょうか?

それは,1対多の関係を1対1の関係で表せるので,コードがシンプルになることが考えられるでしょう.

リストを管理するコードや繰り返しのためのコードをCompositeクラスの中に一度だけ記述するだけで済むためです.

使うべき場面

Compositeパターンを使うべき場面として考えられるのは,
すべてのオブジェクトが全く等価で取り扱われる場合が考えられます.

そのため,1対多の関係を見つけたときに,あるクラスがどのオブジェクトも等価で取り扱っていたならば,Compositeパターンの導入を考えてみてもいいのではないでしょうか.

参考

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?