Skip to content

Commit

Permalink
小傅哥 | 重学 Java 设计模式:实战迭代器模式「模拟公司组织架构树结构关系,深度迭代遍历人员信息输出场景」
Browse files Browse the repository at this point in the history
  • Loading branch information
fuzhengwei committed Jun 23, 2020
1 parent 0694f73 commit aa9c0e6
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 0 deletions.
15 changes: 15 additions & 0 deletions itstack-demo-design-15-00/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http:https://maven.apache.org/POM/4.0.0"
xmlns:xsi="http:https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:https://maven.apache.org/POM/4.0.0 http:https://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>itstack-demo-design</artifactId>
<groupId>org.itstack</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>itstack-demo-design-15-00</artifactId>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.itstack.demo.design.group;

/**
* 雇员
*/
public class Employee {

private String uId; // ID
private String name; // 姓名
private String desc; // 备注

public Employee(String uId, String name) {
this.uId = uId;
this.name = name;
}

public Employee(String uId, String name, String desc) {
this.uId = uId;
this.name = name;
this.desc = desc;
}

public String getuId() {
return uId;
}

public void setuId(String uId) {
this.uId = uId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDesc() {
return desc;
}

public void setDesc(String desc) {
this.desc = desc;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.itstack.demo.design.group;

import org.itstack.demo.design.lang.Collection;
import org.itstack.demo.design.lang.Iterator;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GroupStructure implements Collection<Employee, Link> {

private String groupId; // 组织ID,也是一个组织链的头部ID
private String groupName; // 组织名称
private Map<String, Employee> employeeMap = new ConcurrentHashMap<String, Employee>(); // 雇员列表
private Map<String, List<Link>> linkMap = new ConcurrentHashMap<String, List<Link>>(); // 组织架构关系;id->list
private Map<String, String> invertedMap = new ConcurrentHashMap<String, String>(); // 反向关系链

public GroupStructure(String groupId, String groupName) {
this.groupId = groupId;
this.groupName = groupName;
}

public boolean add(Employee employee) {
return null != employeeMap.put(employee.getuId(), employee);
}

public boolean remove(Employee o) {
return null != employeeMap.remove(o.getuId());
}

public boolean addLink(String key, Link link) {
invertedMap.put(link.getToId(), link.getFromId());
if (linkMap.containsKey(key)) {
return linkMap.get(key).add(link);
} else {
List<Link> links = new LinkedList<Link>();
links.add(link);
linkMap.put(key, links);
return true;
}
}

public boolean removeLink(String key) {
return null != linkMap.remove(key);
}

public Iterator<Employee> iterator() {

return new Iterator<Employee>() {

HashMap<String, Integer> keyMap = new HashMap<String, Integer>();

int totalIdx = 0;
private String fromId = groupId; // 雇员ID,From
private String toId = groupId; // 雇员ID,To

public boolean hasNext() {
return totalIdx < employeeMap.size();
}

public Employee next() {
List<Link> links = linkMap.get(toId);
int cursorIdx = getCursorIdx(toId);

// 同级节点扫描
if (null == links) {
cursorIdx = getCursorIdx(fromId);
links = linkMap.get(fromId);
}

// 上级节点扫描
while (cursorIdx > links.size() - 1) {
fromId = invertedMap.get(fromId);
cursorIdx = getCursorIdx(fromId);
links = linkMap.get(fromId);
}

// 获取节点
Link link = links.get(cursorIdx);
toId = link.getToId();
fromId = link.getFromId();
totalIdx++;

// 返回结果
return employeeMap.get(link.getToId());
}

public int getCursorIdx(String key) {
int idx = 0;
if (keyMap.containsKey(key)) {
idx = keyMap.get(key);
keyMap.put(key, ++idx);
} else {
keyMap.put(key, idx);
}
return idx;
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.itstack.demo.design.group;

/**
* 树节点链路
*/
public class Link {

private String fromId; // 雇员ID
private String toId; // 雇员ID

public Link(String fromId, String toId) {
this.fromId = fromId;
this.toId = toId;
}

public String getFromId() {
return fromId;
}

public void setFromId(String fromId) {
this.fromId = fromId;
}

public String getToId() {
return toId;
}

public void setToId(String toId) {
this.toId = toId;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.itstack.demo.design.lang;

public interface Collection<E, L> extends Iterable<E> {

boolean add(E e);

boolean remove(E e);

boolean addLink(String key, L l);

boolean removeLink(String key);

Iterator<E> iterator();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.itstack.demo.design.lang;

public interface Iterable<E> {

Iterator<E> iterator();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.itstack.demo.design.lang;

public interface Iterator<E> {

boolean hasNext();

E next();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.itstack.demo.design.test;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.itstack.demo.design.group.Employee;
import org.itstack.demo.design.group.GroupStructure;
import org.itstack.demo.design.group.Link;
import org.itstack.demo.design.lang.Iterator;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApiTest {

private Logger logger = LoggerFactory.getLogger(ApiTest.class);

@Test
public void test_iterator() {
GroupStructure groupStructure = new GroupStructure("1", "小傅哥");
groupStructure.add(new Employee("2", "花花", "二级部门"));
groupStructure.add(new Employee("3", "豆包", "二级部门"));
groupStructure.add(new Employee("4", "蹦蹦", "三级部门"));
groupStructure.add(new Employee("5", "大烧", "三级部门"));
groupStructure.add(new Employee("6", "虎哥", "四级部门"));
groupStructure.add(new Employee("7", "玲姐", "四级部门"));
groupStructure.add(new Employee("8", "秋雅", "四级部门"));

groupStructure.addLink("1", new Link("1", "2"));
groupStructure.addLink("1", new Link("1", "3"));

groupStructure.addLink("2", new Link("2", "4"));
groupStructure.addLink("2", new Link("2", "5"));

groupStructure.addLink("5", new Link("5", "6"));
groupStructure.addLink("5", new Link("5", "7"));
groupStructure.addLink("5", new Link("5", "8"));

Iterator<Employee> iterator = groupStructure.iterator();
while (iterator.hasNext()) {
Employee employee = iterator.next();
logger.info("{},雇员 Id:{} Name:{}", employee.getDesc(), employee.getuId(), employee.getName());
}

}

}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<module>itstack-demo-design-14-00</module>
<module>itstack-demo-design-14-01</module>
<module>itstack-demo-design-14-02</module>
<module>itstack-demo-design-15-00</module>
</modules>

<dependencies>
Expand Down

0 comments on commit aa9c0e6

Please sign in to comment.