自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇了解組合模式應(yīng)該怎么用

開發(fā) 前端
假設(shè)我們?cè)陂_發(fā)一個(gè) OA 系統(tǒng)(辦公自動(dòng)化系統(tǒng))。公司的組織結(jié)構(gòu)包含部門和員工兩種數(shù)據(jù)類型。其中,部門又可以包含子部門和員工。

1.什么是組合模式?

Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.

組合模式(Composite Pattern):將對(duì)象組合成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu), 使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

說人話:用于處理樹形結(jié)構(gòu)數(shù)據(jù)。

2.組合模式定義

圖片

①Component 抽象構(gòu)件角色

定義參加組合對(duì)象的共有方法和屬性,可以定義一些默認(rèn)的行為或?qū)傩浴?/p>

②Leaf 葉子節(jié)點(diǎn)

葉子對(duì)象,其下再也沒有其他的子節(jié)點(diǎn),是遍歷的最小單位。

③Composite 樹枝構(gòu)件

樹枝對(duì)象,作用是組合樹枝節(jié)點(diǎn)和葉子節(jié)點(diǎn)形成一個(gè)樹形結(jié)構(gòu)。

3.組合模式通用代碼實(shí)現(xiàn)

/**
* 個(gè)體和整體的抽象
*/
public abstract class Component {
// 個(gè)體和整體都有的共享
public void doSomething(){
// 通用業(yè)務(wù)邏輯
System.out.println("通用業(yè)務(wù)邏輯");
}
}
/**
* 樹枝節(jié)點(diǎn)
*/
public class Composite extends Component{
// 構(gòu)件容器
private ArrayList<Component> componentArrayList = new ArrayList<>();

// 增加一個(gè)葉子節(jié)點(diǎn)或者樹枝節(jié)點(diǎn)
public void add(Component component){
this.componentArrayList.add(component);
}

// 刪除一個(gè)葉子節(jié)點(diǎn)或者樹枝節(jié)點(diǎn)
public void remove(Component component){
this.componentArrayList.remove(component);
}

// 獲取分支下所有葉子節(jié)點(diǎn)和樹枝節(jié)點(diǎn)
public List<Component> getChildren(){
return this.componentArrayList;
}
}
/**
* 葉子節(jié)點(diǎn)
*/
public class Leaf extends Component {

// 覆寫父類方法
@Override
public void doSomething() {
// 葉子節(jié)點(diǎn)邏輯
System.out.println("葉子節(jié)點(diǎn)邏輯");
}
}

測(cè)試:

public class ClientTest {

public static void main(String[] args) {
// 創(chuàng)建一個(gè)根節(jié)點(diǎn)
Composite root = new Composite();
root.doSomething();
// 創(chuàng)建一個(gè)樹枝構(gòu)件
Composite branch = new Composite();
// 創(chuàng)建一個(gè)葉子節(jié)點(diǎn)
Leaf leaf = new Leaf();

// 串聯(lián)起來
root.add(branch);
branch.add(leaf);

display(root);
}

// 通過遞歸遍歷數(shù)
public static void display(Composite root){
for(Component c : root.getChildren()){
if(c instanceof Leaf){ // 葉子節(jié)點(diǎn)
c.doSomething();
}else{
display((Composite) c);
}
}
}
}

這里我們?cè)谂e一個(gè)例子:

假設(shè)我們?cè)陂_發(fā)一個(gè) OA 系統(tǒng)(辦公自動(dòng)化系統(tǒng))。公司的組織結(jié)構(gòu)包含部門和員工兩種數(shù)據(jù)類型。其中,部門又可以包含子部門和員工。

我們希望在內(nèi)存中構(gòu)建整個(gè)公司的人員架構(gòu)圖(部門、子部門、員工的隸屬關(guān)系),并且提供接口計(jì)算出部門的薪資成本(隸屬于這個(gè)部門的所有員工的薪資和)。

圖片

/**
* 部門類和員工類的抽象類
*/
public abstract class HumanResource {
protected long id;
protected double salary;

public HumanResource(long id){
this.id = id;
}

public long getId(){
return id;
}

public abstract double calculateSalary();

}
public class Department extends HumanResource{
private List<HumanResource> subNodes = new ArrayList<>();

public Department(long id){
super(id);
}

@Override
public double calculateSalary() {
double totalSalary = 0d;
for (HumanResource hr : subNodes){
totalSalary += hr.calculateSalary();
}
this.salary = totalSalary;
return totalSalary;
}

public void addSubNode(HumanResource humanResource){
subNodes.add(humanResource);
}
}
public class Employee extends HumanResource{
public Employee(long id,double salary){
super(id);
this.salary = salary;
}

@Override
public double calculateSalary() {
return salary;
}
}

測(cè)試:

public class PersonClientTest {
private static final long ORGANIZATION_ROOT_ID = 1;

public static void main(String[] args) {
// 創(chuàng)建總部門
Department root = new Department(ORGANIZATION_ROOT_ID);

// 創(chuàng)建子部門
Department branch = new Department(2L);

// 創(chuàng)建員工
Employee employee1 = new Employee(21L,2000);
Employee employee2 = new Employee(22L,4000);

root.addSubNode(branch);
branch.addSubNode(employee1);
branch.addSubNode(employee2);

double v = root.calculateSalary();
System.out.println(v);
}

private void buildOrganization(Department department){
// 根據(jù) 部門id 查詢數(shù)據(jù)庫 所有下屬部門 id
// List<Long> subDepartmentIds = departmentRepo.getSubDepartmentIds(department.getId());
List<Long> subDepartmentIds = new ArrayList<>();

for (Long subDepartmentId : subDepartmentIds){
Department subDepartment = new Department(subDepartmentId);
department.addSubNode(subDepartment);
buildOrganization(subDepartment);
}

// 根據(jù)部門id 查詢數(shù)據(jù)庫 其關(guān)聯(lián)員工所有 id
// List<Long> employeeIds = employeeRepo.getDepartmentEmployeeIds(department.getId());
List<Long> employeeIds = new ArrayList<>();
for (Long employeeId : employeeIds){
// 根據(jù) employeeId 查詢數(shù)據(jù)庫得到 salary
// 假設(shè)為 1000
double salary = 1000d;
department.addSubNode(new Employee(employeeId,salary));
}


}
}

4.組合模式優(yōu)點(diǎn)

①高層模塊調(diào)用簡(jiǎn)單

一棵樹形機(jī)構(gòu)中的所有節(jié)點(diǎn)都是Component, 局部和整體對(duì)調(diào)用者來說沒有任何區(qū)別,也就是說, 高層模塊不必關(guān)心自己處理的是單個(gè)對(duì)象還是整個(gè)組合結(jié)構(gòu), 簡(jiǎn)化了高層模塊的代碼。

②節(jié)點(diǎn)自由增加

使用了組合模式后,  如果想增加一個(gè)樹枝節(jié)點(diǎn)、 葉子節(jié)點(diǎn)都很容易, 只要找到它的父節(jié)點(diǎn)就成, 非常容易擴(kuò)展, 符合開閉原則, 對(duì)以后的維護(hù)非常有利。

5.組合模式應(yīng)用場(chǎng)景

只要是樹形結(jié)構(gòu),就可以考慮使用組合模式。

①維護(hù)和展示部分-整體關(guān)系的場(chǎng)景, 如樹形菜單、 文件和文件夾管理。

②從一個(gè)整體中能夠獨(dú)立出部分模塊或功能的場(chǎng)景。

責(zé)任編輯:武曉燕 來源: Java技術(shù)指北
相關(guān)推薦

2021-07-14 10:08:30

責(zé)任鏈模式加工鏈

2021-07-28 10:02:54

建造者模式代碼

2022-03-07 06:34:22

CQRS數(shù)據(jù)庫數(shù)據(jù)模型

2021-07-08 06:30:03

Linux CPULinux 系統(tǒng)

2021-05-20 06:57:16

RabbitMQ開源消息

2022-10-26 07:39:36

MVCC數(shù)據(jù)庫RR

2022-12-19 08:14:30

注解開發(fā)配置

2021-09-16 11:32:19

組合總和

2021-07-10 09:02:42

編程語言 TypeScript

2021-10-28 19:15:02

IPUARM

2020-10-09 08:15:11

JsBridge

2021-09-14 07:26:26

組合問題循環(huán)

2023-06-16 07:41:36

分層架構(gòu)軟件架構(gòu)

2021-08-02 06:34:55

Redis刪除策略開源

2021-11-08 08:42:44

CentOS Supervisor運(yùn)維

2021-11-24 08:51:32

Node.js監(jiān)聽函數(shù)

2022-07-31 20:00:59

云原生云計(jì)算

2021-12-15 11:52:34

GPLLinuxGNU

2023-05-12 08:19:12

Netty程序框架

2021-06-30 00:20:12

Hangfire.NET平臺(tái)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)