首页 > 其他分享 >十三:组合模式:优雅的组织结构

十三:组合模式:优雅的组织结构

时间:2023-04-30 14:04:29浏览次数:29  
标签:组合 十三 void 优雅 add 组件 new OrganizationComponent public

a. 组合模式解读

组合模式是一种结构型设计模式,它允许将对象组织成树形结构,以表示“部分-整体”的层次关系。这种模式让客户端可以统一对待单个对象和组合对象,简化了代码的复杂度。在现实生活中,我们经常会遇到这种需求,如文件系统、组织结构等。

b. 亲身实践:组合模式实现

为了更好地理解组合模式,我们来实现一个简单的组织结构系统。假设我们有三个角色:员工、经理和总监。我们希望在系统中表示这三个角色之间的关系。 首先,我们定义一个表示组织成员的抽象类:

public abstract class OrganizationComponent {
    protected String name;

    public OrganizationComponent(String name) {
        this.name = name;
    }

    public abstract void add(OrganizationComponent component);
    public abstract void remove(OrganizationComponent component);
    public abstract void display(int depth);
}

接下来,我们为每个角色创建一个具体的类,如员工:

public class Employee extends OrganizationComponent {
    public Employee(String name) {
        super(name);
    }

    @Override
    public void add(OrganizationComponent component) {
        throw new UnsupportedOperationException("不支持添加操作");
    }

    @Override
    public void remove(OrganizationComponent component) {
        throw new UnsupportedOperationException("不支持删除操作");
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
    }
}

然后为经理和总监创建类,类似于员工类,但它们可以添加或删除下属:

public class Manager extends OrganizationComponent {
    private List<OrganizationComponent> components = new ArrayList<>();

    public Manager(String name) {
        super(name);
    }

    @Override
    public void add(OrganizationComponent component) {
        components.add(component);
    }

    @Override
    public void remove(OrganizationComponent component) {
        components.remove(component);
    }

    @Override
    public void display(int depth) {
        System.out.println("-".repeat(depth) + name);
        for (OrganizationComponent component : components) {
            component.display(depth + 2);
        }
    }
}

最后,我们可以使用这些类创建一个组织结构:

public class Main {
    public static void main(String[] args) {
        Manager ceo = new Manager("总监");
        Manager manager1 = new Manager("经理1");
        Manager manager2 = new Manager("经理2");

        Employee employee1 = new Employee("员工1");
        Employee employee2 = new Employee("员工2");
        Employee employee3 = new Employee("员工3");

        ceo.add(manager1);
        ceo.add(manager2);

        manager1.add(employee1);
        manager1.add(employee2);

        manager2.add(employee3);

        ceo.display(1);
    }
}

c. 优劣辨析:组合模式的效果

优点:

1、化了客户端的操作,使客户端可以一致性地对待组合对象和单个对象。 2、高度可扩展,可以方便地增加新的组件类型和层次关系。 3、符合开闭原则,不需要修改现有代码就可以添加新的功能。

缺点:

1、在设计中引入了较多的抽象和接口,可能增加了系统的复杂性。 2、不同类型的组件可能存在不同的操作,这可能导致某些方法在某些组件中无法实现,从而引发异常。

d. 组合模式在开源框架中的应用

在实际开发中,组合模式被广泛应用于各种开源框架。一个典型的例子是Apache Wicket,这是一个用于构建Web应用程序的Java组件框架。在Wicket中,页面和组件都可以包含其他组件,形成一个树形结构。Wicket使用组合模式来简化组件的操作和渲染。 下面是一个简单的Wicket应用程序示例,其中使用了组合模式:

public class HomePage extends WebPage {
    public HomePage(final PageParameters parameters) {
        super(parameters);

        // 添加一个Label组件(文本标签)
        add(new Label("message", "Hello, Wicket!"));

        // 添加一个ListView组件(列表视图),用于显示一个字符串列表
        List<String> items = Arrays.asList("Item1", "Item2", "Item3");
        add(new ListView<String>("list", items) {
            @Override
            protected void populateItem(ListItem<String> item) {
                item.add(new Label("item", item.getModelObject()));
            }
        });
    }
}

在这个示例中,HomePage类继承自WebPage,它是Wicket中的一个核心组件。通过调用add方法,我们可以将子组件添加到页面中。Label和ListView组件也可以包含其他子组件,形成一个组织结构。这就是组合模式在Wicket框架中的应用。 总之,组合模式是一种强大而优雅的设计模式,能够简化客户端的操作,同时提供高度的可扩展性。在实际开发中,我们可以结合实际需求灵活运用组合模式,为我们的系统带来优雅的组织结构。

标签:组合,十三,void,优雅,add,组件,new,OrganizationComponent,public
From: https://blog.51cto.com/u_13616584/6237852

相关文章

  • 十八:责任链模式:优雅的任务分派
    a.责任链模式剖析责任链模式是一种行为设计模式,它能够将请求的发送者与接收者解耦。在这个模式中,多个处理对象组成一个链条,每个处理对象在链条中都有机会处理请求。当一个请求沿着链条传递时,处理对象可以选择处理请求或者将其传递给链条上的下一个处理对象。责任链模式使得我们可......
  • 关于组合
    网课里将组合比喻成另一半,继承则是父子之间的继承。组合这玩意,怎么看着这么想单纯地调用呢。就是调用类,而且还可以调用多个,也就是组合多个。Studentstudent=newStudent();然后继承怎么用,在前面加个student.就可了 ......
  • Django笔记三十三之缓存操作
    本文首发于公众号:Hunter后端原文链接:Django笔记三十三之缓存操作这一节介绍一下如何在Django中使用redis做缓存操作。在Django中可以有很多种方式做缓存,比如数据库,比如服务器文件,或者内存,这里介绍用的比较多的使用redis作为缓存。这篇笔记主要内容如下:依赖安装se......
  • #yyds干货盘点# LeetCode程序员面试金典:组合总和 II
    题目:给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 。注意:解集不能包含重复的组合。  示例 1:[10,1,2,7,6,1,5]8示例 2:输入:candidates=[......
  • 组合计数
    组合数\(C^m_n\)=\(\dfrac{n(n-1)(n-2)\cdots(n-m+1)}{m!}\)=\(\dfrac{n!}{m!(n-m)!}\)\(C^m_n\)=\(C^m_{n-1}\)+\(C^{m-1}_{n-1}\)递推法求组合数求组合数Ⅰ\(\quad\)\(C^m_n\)=\(C^m_{n-1}\)+\(C^{m-1}_{n-1}\)//递推法求组合数模板//c[a][b]存储C......
  • 【完全背包的排列问题】NO377. 组合总和 Ⅳ
    [完全背包排列问题]377.组合总和Ⅳ给你一个由不同整数组成的数组nums,和一个目标整数target。请你从nums中找出并返回总和为target的元素组合的个数。题目数据保证答案符合32位整数范围。示例1:输入:nums=[1,2,3],target=4输出:7解释:所有可能的组合为:(1,......
  • 【Jetpack】ViewModel + LiveData + DataBinding 综合使用 ( 核心要点说明 | 组合方式
    文章目录一、ViewModel+LiveData+DataBinding核心要点1、ViewModel使用要点2、LiveData使用要点3、DataBinding使用要点二、ViewModel+LiveData+DataBinding代码示例1、ViewModel+LiveData代码2、build.gradle构建脚本-启用DataBinding3、DataBinding布局文......
  • 于是他迟到的组合数学学习开始了
    加法原理完成一件事,有\(m\)类方法,对于每类方法有\(s_i\)个方案,则此时总方案数就是\(\sum_{i=1}^ms_i\)。乘法原理完成一件事,有\(n\)个步骤,对于每个步骤有\(s_i\)个方案,则此时总方案数就是\(\prod_{i=1}^ns_i\)。排列从\(n\)个数中选出\(m\)个数的一个排列,记......
  • #yyds干货盘点# LeetCode程序员面试金典:组合总和
    题目:给你一个无重复元素的整数数组 candidates和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target的所有 不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates中的同一个数字可以无限制重复被选取。如果至少一个数字的被......
  • 排列与组合
    目录简介排列乘法原理排列数全排列组合加法原理组合数简介排列就是指从给定个数的元素中取出指定个数的元素进行排序。组合则是指从给定个数的元素中仅仅取出指定个数的元素,不考虑排序。排列乘法原理如果完成一个工程需要分\(n\)个步骤,假设\(a_i\)代表第\(i\)个步骤的......