走进设计模式的世界9:我们的公司很复杂-迭代器与组合模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35165632/article/details/83995014

迭代器模式 :

提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。

组合模式 :

允许你将对象组成树形结构来表现“整体/部分”的层次结构。组合能让可以以一致的方式处理个别对象和对象组合。

设计原则:类应该只有一个改变的理由

解释 : 迭代器允许访问聚合的元素,而不需要暴露它的内部结构。迭代器将遍历聚合的工作封装进一个对象中。当使用迭代器的时候,我们依赖聚合提供遍历。迭代器提供了一个通用的接口让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。我们应该努力让一个类只分配一个责任。组合模式允许客户对个别对象以及组合对象一视同仁。组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。在实现组合模式时,有许多设计上的折衷,你要根据需要平衡透明性和安全性。

迭代器模式样例演示:我们有很多部门。

/**
    我们公司有很多种部门
    暂且拿出来行政部门和技术部门作比较
    技术部门是拿array存储的人员信息,因为要控制人员薪资,控制人员的数量。
    行政部门是拿ArrayList储存的人员信息,因为可以轻易的扩展信息。
**/

/**
    行政部门
**/
public class XingZhengDept{
    ArrayList  employees;
    
    public XingZhengDept{
        employees = new ArrayList();
        addEmployee("行政1",3500);
        addEmployee("行政2",3400);
        addEmployee("行政3",3300);
    }
    
    public void addEmployee(String name,double salary){
        Employee e = new Employee(name,salary);
        employees.add(e);   
    }
    
    public ArrayList getEmpItems(){
        return employees;
    }
}


/**
    技术部门
**/
public class JiShuDept{
    Employee[] employees;
    int index = 0;
    static final int MAX = 3;
    public JiShuDept{
        employees = new Employee[3];
        addEmployee("技术1",3500);
        addEmployee("技术2",3400);
        addEmployee("技术3",3300);
    }
    
    public void addEmployee(String name,double salary){
        Employee e = new Employee(name,salary);
        if(index<MAX){
            employees[index]=e;
            index++;
        }else{
            System.out.println("技术已经够多了不能再加人了!!!!");
        }
    }

    public Employee[] getEmpItems(){
        return employees;
    }
}

/**
    如果我想遍历两个部门的所有人员和薪资状况,
    我就分别关注两个订单的返回
**/
public class Test{
    public static void main(String[]args){
        JiShuDept jishu = new JiShuDept();
        XingZhengDept xingzheng = new XingZhengDept();
        Employee[] jishus = jishu.getEmpItems();
        ArrayList xingzhengs = xingzheng.getEmpItems();
        for(Employee e:xingzhengs){
            System.out.println(e);
        }
        for(Employee e:jishus){
            System.out.println(e);
        }        
    }
}

这时候负责统计的类就分别依赖了员工list和员工数组。接下来我们用迭代器改造这两个部分。

/**
 
    先做一个技术部的迭代器

**/

public class JiShuDeptIterator implements Iterator{
    Employee[] employees;
    int index = 0;
    public JiShuDeptIterator (Employee[] employees){
        this.employees = employees; 
    }
    
    public Object next(){
        Employee e = employees[index];
        index++;
        return e;
    }
    
    public boolean hasNext(){
        if(index>=employees.length||employess[index]==null){
            return false;
        }else{
            return true;
        }
    }
    
}



/**
    技术部门
**/
public class JiShuDept{
    Employee[] employees;
    int index = 0;
    static final int MAX = 3;
    public JiShuDept{
        employees = new Employee[3];
        addEmployee("技术1",3500);
        addEmployee("技术2",3400);
        addEmployee("技术3",3300);
    }
    
    public void addEmployee(String name,double salary){
        Employee e = new Employee(name,salary);
        if(index<MAX){
            employees[index]=e;
            index++;
        }else{
            System.out.println("技术已经够多了不能再加人了!!!!");
        }
    }
    
    /**
        因为需要使用迭代器模式,所以这种遍历的方法弃用了。
    **/
    public Employee[] getEmpItems(){
        return employees;
    }
    
    /**
       返回一个迭代器。 
    **/
    public Iterator createIterator(){
        return new JiShuDeptIterator(employees);
    }
}


/**
    由于行政部门是用list储存的所以不需要迭代器
**/

public class XingZhengDept{
    ArrayList  employees;
    
    public XingZhengDept{
        employees = new ArrayList();
        addEmployee("行政1",3500);
        addEmployee("行政2",3400);
        addEmployee("行政3",3300);
    }
    
    public void addEmployee(String name,double salary){
        Employee e = new Employee(name,salary);
        employees.add(e);   
    }
    
    /**
        因为需要使用迭代器模式,所以这种遍历的方法弃用了。
    **/
    public ArrayList getEmpItems(){
        return employees;
    }

    /**
       返回一个迭代器。 
    **/
    public Iterator createIterator(){
        return employees.iterator(); 
    }

}

public class Test{
    public static void main(String[]agrs){
        // 创建行政部门
        XingZhengDept xingzheng = new XingZhengDept();
        // 创建技术部门
        JiShuDept jishu = new JiShuDept();
        // 打印行政部门信息
        printEmp(xingzheng.createIterator());
        // 打印技术部门信息
        printEmp(jishu.createIterator());
    }
    /**
      打印员工信息
    **/
    public void printEmp(Iterator iterator){
       while(iterator.hasNext()){
            Employee e = (Employee)iterator.next();
            System.out.println("员工:"+e.getName());
            System.out.println("薪资:"+e.getSalary());    
       }
    }
}

按照如上改造,两个部门被改造成了迭代器模式。那组合模式又是什么样的呢?????

/**
   情景如下:
   我们公司有三个大的部门
   1.营销部
   2.技术部
   3.行政部 
   营销部直属一个经理,和两个营销部长。
   营销部下辖营销一部和营销二部。
   接下来我们看如何设计。   
**/

//首先我们把部门和员工都抽象成公司成员的一部分
public abstract class Member{
    // 定义公有的方法添加员工/部门
    public void add(Member m){
        throw new Exception("未添加实现");
    }
    
    public Member getChild(int i){
        throw new Exception("未添加实现");
    }
    
    public String getName(){
        throw new Exception("未添加实现");
    }

    public double getSalary(){
        throw new Exception("未添加实现");
    }

    public void print(){
        throw new Exception("未添加实现");
    }
}

/**
    员工类
**/
public class Emp extends Member{
    // 名称
    private String name;
    // 薪资
    private double salary;
    // 构造方法
    public Emp(String name,double salary){
        this.name = name;
        this.salary = salary;
    }
    
    // 重写getName方法
    public String getName(){
        return name;
    }

    // 重写getSalary方法
    public double getSalary(){
        return salary;
    }

    // 重写print方法
    public void print(){
        System.out.println("名字:"+name);
        System.out.println("薪水:"+salary);
    }
}

/**
    部门类
**/

public class Dept extends Members{
    ArrayList members;
    String deptName;
    // 构造方法
    public Dept (String deptName){
        this.deptName = deptName;
    }
    
    // 重写getChild方法
    public Member getChild(int i){
        return (Member)members.get(i);
    }
    // 重写print方法
    public void print(){
        System.out.println("部门为:"+deptName);
        System.out.println("--------------------------------------");
    }
}

把部门和员工都放到一个门类下,这样便利的时候只需要根据不同的种类去判断就可以了。

猜你喜欢

转载自blog.csdn.net/qq_35165632/article/details/83995014