设计模式 - 组合模式理解及示例

组合模式

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

示例 - 导航菜单

每个菜单都有自己的属性(包含:icon、名称、链接、子菜单)
设计一个菜单类

<?php
namespace App\Console\Test\Menu;

/**
 * 菜单
 */
class Menu
{
	//菜单名称
    public string $name;

	//菜单icon
    public string $icon;

	//点击链接
    public string $url;

	//子菜单
    public array $items = [];

    public function __construct(string $name)
    {
        $this->setName($name);
    }

    public function addMenu(Menu $menu)
    {
        array_push($this->items,$menu);
    }

    public function setName(string $name)
    {
        $this->name = $name;
    }

    public function display()
    {
        dd($this);
    }
	
	//菜单转数组
    public function toArray() : array
    {
        $data = [
            'name'  =>  $this->getName()
        ];
        if(!empty($this->url))
            $data['url'] = $this->getUrl();
        if(!empty($this->icon))
            $data['icon']= $this->getIcon();

        if(!empty($this->items))
        {
            $data['menus'] = [];
            foreach($this->items as $item)
            {
                array_push($data['menus'],$item->toArray());
            }
        }

        return $data;
    }

    /**
     * @return string
     */
    public function getIcon(): string
    {
        return $this->icon;
    }

    /**
     * @param string $icon
     */
    public function setIcon(string $icon): void
    {
        $this->icon = $icon;
    }

    /**
     * @return string
     */
    public function getUrl(): string
    {
        return $this->url;
    }

    /**
     * @param string $url
     */
    public function setUrl(string $url): void
    {
        $this->url = $url;
    }

    /**
     * @return array
     */
    public function getItems(): array
    {
        return $this->items;
    }

    /**
     * @param array $items
     */
    public function setItems(array $items): void
    {
        $this->items = $items;
    }

    public function getName() : string
    {
        return $this->name;
    }
}

接下来我们开始组装菜单。在组装前我们先定义一个菜单配置,声明菜单与菜单之间的关系

//菜单配置
public function getMenuData()
{
    return [
        'name'      =>  '菜单',
        'menus'     =>  [
            [
                'name'  =>  '系统设置',
                'icon'  =>  'aaa',
                'menus' =>  [
                    [
                        'name'  =>  '文件上传配置',
                        'url'   =>  '1',
                        'icon'  =>  '123'
                    ],
                    [
                        'name'  =>  '系统设置',
                        'url'   =>  '2',
                        'icon'  =>  '123'
                    ],
                    [
                        'name'  =>  '支付设置',
                        'url'   =>  '3',
                        'icon'  =>  '123'
                    ],
                    [
                        'name'  =>  '网站设置',
                        'url'   =>  '4',
                        'icon'  =>  '123'
                    ]
                ]
            ],
            [
                'name'  =>  "用户管理",
                'icon'  =>  'bbb',
                'menus' =>  [
                    [
                        'name'  =>  '粉丝管理',
                        'url'   =>  '5'
                    ],
                    [
                        'name'  =>  '商户管理',
                        'url'   =>  '6'
                    ]
                ]
            ],
            [
                'name'  =>  '应用管理',
                'icon'  =>  'ccc',
                'menus' =>  [
                    [
                        'name'  =>  '秒杀',
                        'url'   =>  '7'
                    ],
                    [
                        'name'  =>  '砍价',
                        'url'   =>  '8'
                    ],
                ]
            ]
        ]
    ];
}

组装菜单

//组装菜单方法
public function structMenu(array &$menuConfig) : Menu
{
	if(!isset($menuConfig['name']))
	    throw new \Exception("not get name",101);
	
	$menu = new Menu($menuConfig['name']);
	
	//属性
	if(isset($menuConfig['url']))
	    $menu->setUrl($menuConfig['url']);
	
	//属性
	if(isset($menuConfig['icon']))
	    $menu->setIcon($menuConfig['icon']);
	
	//子菜单
	if(isset($menuConfig['menus']) && !empty($menuConfig['menus']))
	{
	    foreach($menuConfig['menus'] as $childrenMenuConfig)
	    {
	        $menu->addMenu($this->structMenu($childrenMenuConfig));
	    }
	}

   return $menu;
}
public function index16()
{
	//获取菜单配置
	$menuConfig = $this->getMenuData();
	
	//根据菜单配置组装菜单
	$menu = $this->structMenu($menuConfig);
	
	//打印菜单
	dd($menu->toArray());
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值