组合模式

正文:https://refactoringguru.cn/design-patterns/composite

Go代码:https://refactoringguru.cn/design-patterns/composite/go/example

module composite_module

    implicit none
    private

    public :: file_type, folder_type

    type, abstract :: component_type
    contains
        procedure(component_type_search), deferred :: search
    end type component_type

    type, extends(component_type) :: file_type
        character(:), allocatable :: name
    contains
        procedure :: search => file_type_search
        procedure :: get_name => file_type_get_name
    end type file_type

    type node_t
        class(component_type), pointer :: node
    end type node_t

    type, extends(component_type) :: folder_type
        type(node_t), allocatable :: components(:)
        character(:), allocatable :: name
    contains
        procedure :: search => folder_type_search
    end type folder_type

    abstract interface
        subroutine component_type_search(self, keyward)
            import component_type
            class(component_type), intent(inout) :: self
            character(*), intent(in) :: keyward
        end subroutine component_type_search
    end interface

contains

    subroutine file_type_search(self, keyward)
        class(file_type), intent(inout) :: self
        character(*), intent(in) :: keyward
        print *, "Searching for keyword ", keyward, " in file ", self%name
    end subroutine file_type_search

    function file_type_get_name(self) result(name)
        class(file_type), intent(inout) :: self
        character(:), allocatable :: name
        name = self%name
    end function file_type_get_name

    ! - - - - - - - - - -

    subroutine folder_type_search(self, keyward)
        class(folder_type), intent(inout) :: self
        character(*), intent(in) :: keyward
        integer :: i
        print *, "Searching recursively for keyword ", keyward, " in folder ", self%name
        if (size(self%components) == 0) return
        do i = 1, size(self%components)
            call self%components(i)%node%search(keyward)
        end do
    end subroutine folder_type_search

end module composite_module
program composite_main
    use composite_module, only: file_type, folder_type
    implicit none
    type(file_type), target :: file1, file2, file3
    type(folder_type), target :: folder1
    type(folder_type) :: folder2

    file1%name = "File1"
    file2%name = "File2"
    file3%name = "File3"

    folder1%name = "Folder1"
    folder2%name = "Folder2"

    allocate (folder1%components(1))
    folder1%components(1)%node => file1

    allocate (folder2%components(3))
    folder2%components(1)%node => file2
    folder2%components(2)%node => file3
    folder2%components(3)%node => folder1

    call folder2%search("rose")

end program composite_main

!> Results shall be:

!  Searching recursively for keyword rose in folder Folder2
!  Searching for keyword rose in file File2
!  Searching for keyword rose in file File3
!  Searching recursively for keyword rose in folder Folder1
!  Searching for keyword rose in file File1