组合模式
正文: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