山西怀仁建设银行,佛山网站优化公司,石家庄网站设计公司,建立局域网网站一、组合模式
1.1概述 组合模式是一种结构型设计模式#xff0c;它允许将对象组合成树形结构#xff0c;以表示“部分-整体”的层次结构。组合模式使得客户端可以一致地对待单个对象和对象组合#xff0c;从而将复杂的层次结构展现为一个统一的树形结构。 在组合模式中它允许将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以一致地对待单个对象和对象组合从而将复杂的层次结构展现为一个统一的树形结构。 在组合模式中一般会定义一个抽象类或接口来表示组合中的所有对象包括叶子对象和容器对象叶子对象表示树形结构中的最底层节点容器对象表示树形结构中的分支节点同时容器对象可以包含叶子对象或其他容器对象。 组合模式能够有效地简化代码结构提高代码的可维护性和可扩展性同时也具有良好的透明性和灵活性。在实际编程中组合模式广泛应用于树形结构的处理、图形绘制、文件系统等领域。 对于这个图片肯定会非常熟悉上图我们可以看做是一个文件系统对于这样的结构我们称之为树形结构。在树形结构中可以通过调用某个方法来遍历整个树当我们找到某个叶子节点后就可以对叶子节点进行相关的操作。可以将这颗树理解成一个大的容器容器里面包含很多的成员对象这些成员对象即可是容器对象也可以是叶子对象。但是由于容器对象和叶子对象在功能上面的区别使得我们在使用的过程中必须要区分容器对象和叶子对象但是这样就会给客户带来不必要的麻烦作为客户而已它始终希望能够一致的对待容器对象和叶子对象。 1.2结构 组合模式主要包含三种角色 抽象根节点Component定义系统各层次对象的共有方法和属性定义组合中所有对象的通用接口可以是抽象类或接口包含了组合对象和叶子对象的公共操作。树枝节点Composite定义树枝节点的行为存储子节点组合树枝节点和叶子节点形成一个树形结构。表示组合对象包含了一个子对象的集合并实现了抽象构件中的公共操作。叶子节点Leaf叶子节点对象其下再无分支是系统层次遍历的最小单位。 1.3实现
软件菜单
如下图我们在访问别的一些管理系统时经常可以看到类似的菜单。一个菜单可以包含菜单项菜单项是指不再包含其他内容的菜单条目也可以包含带有其他菜单项的菜单因此使用组合模式描述菜单就很恰当我们的需求是针对一个菜单打印出其包含的所有菜单以及菜单项的名称。 要实现该案例我们先画出类图 抽象构件角色抽象根节点
package com.yanyu.Component;//菜单组件 不管是菜单还是菜单项都应该继承该类
public abstract class MenuComponent {protected String name;protected int level;//添加菜单public void add(MenuComponent menuComponent){throw new UnsupportedOperationException();}//移除菜单public void remove(MenuComponent menuComponent){throw new UnsupportedOperationException();}//获取指定的子菜单public MenuComponent getChild(int i){throw new UnsupportedOperationException();}//获取菜单名称public String getName(){return name;}//打印菜单public void print(){throw new UnsupportedOperationException();}
} 树枝节点组合部件
package com.yanyu.Component;import java.util.ArrayList;
import java.util.List;//菜单类继承自菜单组件
public class Menu extends MenuComponent {private ListMenuComponent menuComponentList;//构造函数public Menu(String name, int level){this.level level;this.name name;menuComponentList new ArrayListMenuComponent();}//添加菜单项或子菜单Overridepublic void add(MenuComponent menuComponent) {menuComponentList.add(menuComponent);}//移除菜单项或子菜单Overridepublic void remove(MenuComponent menuComponent) {menuComponentList.remove(menuComponent);}//获取指定的子菜单Overridepublic MenuComponent getChild(int i) {return menuComponentList.get(i);}//打印菜单及子菜单Overridepublic void print() {for (int i 1; i level; i) {System.out.print(--);}System.out.println(name);for (MenuComponent menuComponent : menuComponentList) {menuComponent.print();}}
}叶子节点叶子构件
package com.yanyu.Component;//菜单项类继承自菜单组件
public class MenuItem extends MenuComponent {//构造函数public MenuItem(String name, int level) {this.name name;this.level level;}//打印菜单项Overridepublic void print() {for (int i 1; i level; i) {System.out.print(--);}System.out.println(name);}
}客户端类
package com.yanyu.Component;public class Client {public static void main(String[] args) {//创建菜单树MenuComponent menu1 new Menu(菜单管理, 2);menu1.add(new MenuItem(页面访问, 3));menu1.add(new MenuItem(展开菜单, 3));menu1.add(new MenuItem(编辑菜单, 3));menu1.add(new MenuItem(删除菜单, 3));menu1.add(new MenuItem(新增菜单, 3));MenuComponent menu2 new Menu(权限管理, 2);menu2.add(new MenuItem(页面访问, 3));menu2.add(new MenuItem(提交保存, 3));MenuComponent menu3 new Menu(角色管理, 2);menu3.add(new MenuItem(页面访问, 3));menu3.add(new MenuItem(新增角色, 3));menu3.add(new MenuItem(修改角色, 3));//创建一级菜单MenuComponent component new Menu(系统管理, 1);component.add(menu1);component.add(menu2);component.add(menu3);component.print();}
} 组合模式可以清楚地定义分层次的复杂对象表示对象的全部或部分层次它让客户端忽略了层次的差异方便对整个层次结构进行控制。客户端可以一致地使用一个组合结构或其中单个对象不必关心处理的是单个对象还是整个组合结构简化了客户端代码。在组合模式中增加新的树枝节点和叶子节点都很方便无须对现有类库进行任何修改符合“开闭原则”。组合模式为树形结构的面向对象实现提供了一种灵活的解决方案通过叶子节点和树枝节点的递归组合可以形成复杂的树形结构但对树形结构的控制却非常简单。 1.4组合模式的分类 在使用组合模式时根据抽象构件类的定义形式我们可将组合模式分为透明组合模式和安全组合模式两种形式。 透明组合模式 透明组合模式中抽象根节点角色中声明了所有用于管理成员对象的方法比如在示例中 MenuComponent 声明了 add、remove 、getChild 方法这样做的好处是确保所有的构件类都有相同的接口。透明组合模式也是组合模式的标准形式。 透明组合模式的缺点是不够安全因为叶子对象和容器对象在本质上是有区别的叶子对象不可能有下一个层次的对象即不可能包含成员对象因此为其提供 add()、remove() 等方法是没有意义的这在编译阶段不会出错但在运行阶段如果调用这些方法可能会出错如果没有提供相应的错误处理代码 安全组合模式 在安全组合模式中在抽象构件角色中没有声明任何用于管理成员对象的方法而是在树枝节点 Menu 类中声明并实现这些方法。安全组合模式的缺点是不够透明因为叶子构件和容器构件具有不同的方法且容器构件中那些用于管理成员对象的方法没有在抽象构件类中定义因此客户端不能完全针对抽象编程必须有区别地对待叶子构件和容器构件。 1.5使用场景 如果你需要实现树状对象结构 可以使用组合模式。 组合模式为你提供了两种共享公共接口的基本元素类型 简单叶节点和复杂容器。 容器中可以包含叶节点和其他容器。 这使得你可以构建树状嵌套递归对象结构。 如果你希望客户端代码以相同方式处理简单和复杂元素 可以使用该模式。 组合模式中定义的所有元素共用同一个接口。 在这一接口的帮助下 客户端不必在意其所使用的对象的具体类。 组合模式正是应树形结构而生所以组合模式的使用场景就是出现树形结构的地方。比如文件目录显示多级目录呈现等树形结构数据的操作。 二、享元模式
2.1概述 享元模式是一种结构型设计模式旨在减少内存占用和提高性能。它将对象分解为可共享的和不可共享的部分。可共享的部分是多个对象共有的、不变的部分它们可以被多个对象共享使用从而减少内存占用。不可共享的部分是对象不同的、可变的部分每个对象各自拥有不同的副本。 通过应用享元模式我们可以大幅度减少系统中的对象数量提高系统的性能和响应速度。然而享元模式会增加程序的复杂性和开发难度因为需要将对象分解为可共享和不可共享的部分并维护对象的共享池。因此需要在实际应用中根据具体情况进行权衡和取舍。 定义 运用共享技术来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销从而提高系统资源的利用率。 2.2结构 享元Flyweight 模式中存在以下两种状态 内部状态即不会随着环境的改变而改变的可共享部分。外部状态指随环境改变而改变的不可以共享的部分。享元模式的实现要领就是区分应用中的这两种状态并将外部状态外部化。 享元模式的主要有以下角色 抽象享元角色Flyweight通常是一个接口或抽象类在抽象享元类中声明了具体享元类公共的方法这些方法可以向外界提供享元对象的内部数据内部状态同时也可以通过这些方法来设置外部数据外部状态。具体享元Concrete Flyweight角色 它实现了抽象享元类称为享元对象在具体享元类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类为每一个具体享元类提供唯一的享元对象。非享元Unsharable Flyweight)角色 并不是所有的抽象享元类的子类都需要被共享不能被共享的子类可设计为非共享具体享元类当需要一个非共享具体享元类的对象时可以直接通过实例化创建。享元工厂Flyweight Factory角色 负责创建和管理享元角色。当客户对象请求一个享元对象时享元工厂检査系统中是否存在符合要求的享元对象如果存在则提供给客户如果不存在的话则创建一个新的享元对象。 2.3实现
【例】俄罗斯方块
下面的图片是众所周知的俄罗斯方块中的一个个方块如果在俄罗斯方块这个游戏中每个不同的方块都是一个实例对象这些对象就要占用很多的内存空间下面利用享元模式进行实现。 先来看类图 抽象享元
package com.yanyu.Flyweight;// 抽象享元类
public abstract class AbstractBox {// 声明一个抽象方法用于获取方块形状public abstract String getShape();// 实现一个公共方法用于显示方块的形状和颜色public void display(String color) {System.out.println(方块形状 this.getShape() 颜色 color);}
}
具体亨元
package com.yanyu.Flyweight;/*** IBox是一个继承自AbstractBox的类。* 它代表一个I形状的方块。*/
public class IBox extends AbstractBox {/*** 重写了AbstractBox中的getShape方法。* 返回I表示这个方块是一个I形状的方块。*/Overridepublic String getShape() {return I;}
}package com.yanyu.Flyweight;public class LBox extends AbstractBox {Overridepublic String getShape() {return L;}
}
package com.yanyu.Flyweight;public class OBox extends AbstractBox {Overridepublic String getShape() {return O;}
}享元工厂
package com.yanyu.Flyweight;import java.util.HashMap;// 创建一个BoxFactory类
public class BoxFactory {// 创建一个静态的HashMap用于存储不同类型的AbstractBoxprivate static HashMapString, AbstractBox map;// 私有构造函数初始化HashMap并将不同类型的AbstractBox放入其中private BoxFactory() {map new HashMapString, AbstractBox();AbstractBox iBox new IBox(); // 创建IBox对象AbstractBox lBox new LBox(); // 创建LBox对象AbstractBox oBox new OBox(); // 创建OBox对象map.put(I, iBox); // 将IBox对象放入HashMapmap.put(L, lBox); // 将LBox对象放入HashMapmap.put(O, oBox); // 将OBox对象放入HashMap}// 创建一个静态内部类SingletonHolder用于实现单例模式private static class SingletonHolder {private static final BoxFactory INSTANCE new BoxFactory(); // 创建BoxFactory的单例实例}// 获取BoxFactory的实例public static final BoxFactory getInstance() {return SingletonHolder.INSTANCE; // 返回BoxFactory的单例实例}// 根据key获取对应的AbstractBoxpublic AbstractBox getBox(String key) {return map.get(key); // 根据key从HashMap中获取对应的AbstractBox对象}
}客户端类
package com.yanyu.Flyweight;public class Client {public static void main(String[] args) {AbstractBox box1 BoxFactory.getInstance().getBox(I);box1.display(灰色);AbstractBox box2 BoxFactory.getInstance().getBox(L);box2.display(绿色);AbstractBox box3 BoxFactory.getInstance().getBox(O);box3.display(灰色);// 再次获取相同的图形对象AbstractBox box4 BoxFactory.getInstance().getBox(O);box4.display(红色);System.out.println(再次获取到的图形对象是否是同一个对象: (box3 box4));}
}2.4 优缺点 1优点 极大减少内存中相似或相同对象数量节约系统资源提供系统性能享元模式中的外部状态相对独立且不影响内部状态 2缺点 为了使对象可以共享需要将享元对象的部分状态外部化分离内部状态和外部状态使程序逻辑复杂 2.5应用场景 仅在程序必须支持大量对象且没有足够的内存容量时使用享元模式。 应用该模式所获的收益大小取决于使用它的方式和情景。 它在下列情况中最有效 程序需要生成数量巨大的相似对象这将耗尽目标设备的所有内存对象中包含可抽取且能在多个对象间共享的重复状态。 2.6 JDK源码解析
Integer类使用了享元模式。我们先看下面的例子 public class Demo {public static void main(String[] args) {Integer i1 127;Integer i2 127;
System.out.println(i1和i2对象是否是同一个对象 (i1 i2));
Integer i3 128;Integer i4 128;
System.out.println(i3和i4对象是否是同一个对象 (i3 i4));}
}
运行上面代码结果如下 三、组合模式实验 任务描述 使用组合模式设计一个杀毒软件AntiVirus的框架该软件既可以对某个文件夹Folder杀毒也可以对某个指定的文件File进行杀毒文件种类包括文本文件 TextFile图片文件 ImageFile、视频文件 VideoFile。 本关任务根据 UML 类图编程模拟实现。 实现方式 确保应用的核心模型能够以树状结构表示。 尝试将其分解为简单元素和容器。 记住 容器必须能够同时包含简单元素和其他容器。 声明组件接口及其一系列方法 这些方法对简单和复杂元素都有意义。 创建一个叶节点类表示简单元素。 程序中可以有多个不同的叶节点类。 创建一个容器类表示复杂元素。 在该类中 创建一个数组成员变量来存储对于其子元素的引用。 该数组必须能够同时保存叶节点和容器 因此请确保将其声明为组合接口类型。实现组件接口方法时 记住容器应该将大部分工作交给其子元素来完成。 最后 在容器中定义添加和删除子元素的方法。 记住这些操作可在组件接口中声明。 这将会违反接口隔离原则因为叶节点类中的这些方法为空。 但是这可以让客户端无差别地访问所有元素 即使是组成树状结构的元素。 编程要求 根据提示在右侧编辑器 Begin-End 内补充 AbstractFile.java 和 Folder.java 文件代码其它文件不需要修 抽象构建
package step1;
//抽象文件类:抽象构件
/********** Begin *********/public abstract class AbstractFile {public abstract void add(AbstractFile file);public abstract void remove(AbstractFile file);public abstract void scan();
}/********** End *********/
组合部件
package step1;import java.util.ArrayList;
import java.util.List;// 文件夹类属于组合模式中的容器构件
public class Folder extends AbstractFile {private String name; // 文件夹名称private ListAbstractFile files new ArrayList(); // 存储文件夹中的文件或子文件夹public Folder(String name) {this.name name;}// 添加文件或子文件夹public void add(AbstractFile file) {files.add(file);}// 移除文件或子文件夹public void remove(AbstractFile file) {files.remove(file);}// 获取子文件或子文件夹public AbstractFile getChild(int i) {return files.get(i);}// 扫描文件夹public void scan() {System.out.println(开始扫描文件夹 name); // 打印扫描文件夹的信息for (AbstractFile file : files) {file.scan(); // 调用子文件或子文件夹的扫描方法}}
}叶子构建
package step1;//图片文件类:叶子构件
public class ImageFile extends AbstractFile{private String fileName;public ImageFile(String fileName){this.fileName fileName;}Overridepublic void add(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void remove(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void scan() {System.out.println(扫描图片文件:fileName);}
}package step1;//文本文件类:叶子构件
public class TextFile extends AbstractFile{private String fileName;public TextFile(String fileName){this.fileName fileName;}Overridepublic void add(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void remove(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void scan() {System.out.println(扫描文本文件:fileName);}
}package step1;//视频文件类:叶子构件
public class VideoFile extends AbstractFile{private String fileName;public VideoFile(String fileName){this.fileName fileName;}Overridepublic void add(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void remove(AbstractFile element) {System.out.println(对不起不支持该方法);}Overridepublic void scan() {System.out.println(扫描视频文件:fileName);}
}客户端类
// 定义客户端类
package step1;public class Client {public static void main(String[] args) {// 创建文件和文件夹对象AbstractFile file1, file2, file3, file4, file5, folder1, folder2, folder3;// 创建各种类型的文件对象file1 new ImageFile(pic1.gif);file2 new ImageFile(pic2.jpg);file3 new TextFile(txt1.txt);file4 new TextFile(txt2.doc);file5 new VideoFile(video1.rmvb);// 创建文件夹对象folder1 new Folder(图片文件夹);folder1.add(file1); // 将图片文件添加到图片文件夹中folder1.add(file2);folder2 new Folder(文本文件夹);folder2.add(file3); // 将文本文件添加到文本文件夹中folder2.add(file4);folder3 new Folder(个人资料);folder3.add(file5); // 将视频文件添加到个人资料文件夹中folder3.add(folder1); // 将图片文件夹添加到个人资料文件夹中folder3.add(folder2); // 将文本文件夹添加到个人资料文件夹中// 扫描文件夹folder3.scan(); // 调用文件夹的扫描方法实现对整个文件夹结构的扫描}
}四、享元模式 实验 任务描述 在一个虚拟仿真程序中需要渲染一片森林 1,000,000 棵树 每棵树对象都包含一些状态品种名 name屏幕坐标 x,屏幕坐标 y,颜色 color其它附带数据 otherTreeData。 本关任务太多树对象包含重复数据因此我们可用享元模式来将这些数值存储在单独的享元对象中TreeType 类。请分析“树”的状态中哪些是外在状态哪些是内部状态然后补全代码。 实现方式 将需要改写为享元的类成员变量拆分为两个部分内在状态包含不变的、 可在许多对象中重复使用的数据的成员变量。外在状态 包含每个对象各自不同的情景数据的成员变量 保留类中表示内在状态的成员变量 并将其属性设置为不可修改。 这些变量仅可在构造函数中获得初始数值 找到所有使用外在状态成员变量的方法 为在方法中所用的每个成员变量新建一个参数 并使用该参数代替成员变量 你可以有选择地创建工厂类来管理享元缓存池 它负责在新建享元时检查已有的享元。 如果选择使用工厂 客户端就只能通过工厂来请求享元 它们需要将享元的内在状态作为参数传递给工厂 客户端必须存储和计算外在状态 情景 的数值 因为只有这样才能调用享元对象的方法。 为了使用方便 外在状态和引用享元的成员变量可以移动到单独的情景类中。 编程提示 TreeType.java 内在状态享元类 Tree.java树对象类 TreeFactory.java内在状态享元工厂类 Forest.java森林对象类。 本地 windows 系统调式时可将图形代码恢复观看实际效果。提交测试时务必屏蔽图形代码 编程要求 根据提示在右侧编辑器 Begin-End 内补充 “Tree.java”,“TreeType.java” 和 “TreeFactory.java” 文件的代码其它文件不需要更改计算对比优化前后分别占用的内存数。 抽象享元
import java.awt.*;public class Tree {// 享元对象和外在状态private int x; // 外在状态树的x坐标private int y; // 外在状态树的y坐标private TreeType type; // 享元对象树的类型// 构造方法public Tree(int x, int y, TreeType type) {this.x x;this.y y;this.type type;}public void draw(Graphics g) {type.draw(g, x, y); // 调用享元对象的绘制方法}
}import java.awt.*;public class TreeType {/********** 内在状态 *********/// 内在状态private String name; // 树的名称private Color color; // 树的颜色private String texture; // 树的纹理/********** End *********//********** 构造方法 *********/public TreeType(String name, Color color, String texture) {this.name name;this.color color;this.texture texture;}/********** End *********/public void draw(Graphics g, int x, int y) {//本地测试时可使用图形化代码/*g.setColor(Color.BLACK);g.fillRect(x - 1, y, 3, 5);g.setColor(color);g.fillOval(x - 5, y - 10, 10, 10);*/}
}享元工厂
import java.awt.*;
import java.util.HashMap;
import java.util.Map;public class TreeFactory {private MapString, TreeType treeTypes new HashMap();public TreeType getTreeType(String name, Color color, String texture) {String key name color texture; // 内在状态的唯一关键字参数TreeType result treeTypes.get(key);if (result null) {// 创建一个享元对象result new TreeType(name, color, texture);// 将新的享元对象放入对象池中treeTypes.put(key, result);}return result;}public int getTotalTreetype() {return treeTypes.size();}
}在上述代码中treeTypes.get(key)和treeTypes.put(key, result)是享元模式中的关键操作。具体解释如下 - treeTypes.get(key): 这行代码用于从对象池中获取具有特定内在状态的享元对象。在这里我们使用key作为唯一的标识符来检索享元对象。如果对象池中已经存在具有相同内在状态的享元对象则直接返回该对象否则返回null。 - treeTypes.put(key, result): 这行代码用于将新创建的享元对象放入对象池中。如果对象池中不存在具有相同内在状态的享元对象那么我们需要将新创建的享元对象放入对象池中以便后续重复使用。 这两行代码共同实现了享元模式中的对象共享和复用通过对象池管理和重复利用享元对象以节省内存和提高性能。 import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;public class Forest /*extends JFrame*/ {private ListTree trees new ArrayList(); // 存储森林中的树private TreeFactory treeFactory; // 树工厂对象用于创建和管理树的类型public Forest(TreeFactory treeFactory) {this.treeFactory treeFactory;}// 添加树到森林中public void plantTree(int x, int y, String name, Color color, String otherTreeData) {// 从树工厂中获取树的类型TreeType type treeFactory.getTreeType(name, color, otherTreeData);// 创建树对象并添加到森林中Tree tree new Tree(x, y, type);trees.add(tree);}// 获取森林中的树的数量public int getTotalTree() {return trees.size();}// 获取树工厂中的树的类型数量public int getTotalTreetype() {return treeFactory.getTotalTreetype();}//Override// 本地测试时,可继承JFrame类并恢复以下图形化代码/*public void paint(Graphics graphics) {for (Tree tree : trees) {tree.draw(graphics);}}*/
}客户端类
import java.awt.*;// 客户端类用于测试和演示
public class Client {// 画布大小static int CANVAS_SIZE 500;// 需要绘制的树的数量static int TREES_TO_DRAW 1000000;// 树的类型数量static int TREE_TYPES 2;public static void main(String[] args) {// 创建树工厂TreeFactory factory new TreeFactory();// 创建森林Forest forest new Forest(factory);// 根据树的类型数量和需要绘制的树的数量随机生成不同类型的树并添加到森林中for (int i 0; i Math.floor(TREES_TO_DRAW / TREE_TYPES); i) {// 随机生成夏季橡树并添加到森林中forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE),Summer Oak, Color.GREEN, Oak texture stub);// 随机生成秋季橡树并添加到森林中forest.plantTree(random(0, CANVAS_SIZE), random(0, CANVAS_SIZE),Autumn Oak, Color.ORANGE, Autumn Oak texture stub);}// 输出绘制的树的数量System.out.println(forest.getTotalTree() trees drawn);// 输出内存使用情况System.out.println(Memory usage:);System.out.println(Tree size (8 bytes) * forest.getTotalTree());System.out.println( TreeTypes size (~30 bytes) * forest.getTotalTreetype() );System.out.println(Total: ((forest.getTotalTree() * 8 forest.getTotalTreetype() * 30) / 1024 / 1024) MB (instead of ((forest.getTotalTree() * 38) / 1024 / 1024) MB));}// 生成指定范围内的随机数private static int random(int min, int max) {return min (int) (Math.random() * ((max - min) 1));}
} 文章转载自: http://www.morning.bndkf.cn.gov.cn.bndkf.cn http://www.morning.zrkws.cn.gov.cn.zrkws.cn http://www.morning.msbpb.cn.gov.cn.msbpb.cn http://www.morning.jzlkq.cn.gov.cn.jzlkq.cn http://www.morning.tsnwf.cn.gov.cn.tsnwf.cn http://www.morning.gycyt.cn.gov.cn.gycyt.cn http://www.morning.fcpjq.cn.gov.cn.fcpjq.cn http://www.morning.tpqzs.cn.gov.cn.tpqzs.cn http://www.morning.plzgt.cn.gov.cn.plzgt.cn http://www.morning.jtnph.cn.gov.cn.jtnph.cn http://www.morning.rrgqq.cn.gov.cn.rrgqq.cn http://www.morning.wtcyz.cn.gov.cn.wtcyz.cn http://www.morning.sjwzl.cn.gov.cn.sjwzl.cn http://www.morning.xfxnq.cn.gov.cn.xfxnq.cn http://www.morning.cwyfs.cn.gov.cn.cwyfs.cn http://www.morning.dwtdn.cn.gov.cn.dwtdn.cn http://www.morning.ymfzd.cn.gov.cn.ymfzd.cn http://www.morning.npxcc.cn.gov.cn.npxcc.cn http://www.morning.sqfrg.cn.gov.cn.sqfrg.cn http://www.morning.pdmml.cn.gov.cn.pdmml.cn http://www.morning.mtsgx.cn.gov.cn.mtsgx.cn http://www.morning.mqwdh.cn.gov.cn.mqwdh.cn http://www.morning.mlfgx.cn.gov.cn.mlfgx.cn http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn http://www.morning.rxtxf.cn.gov.cn.rxtxf.cn http://www.morning.trhlb.cn.gov.cn.trhlb.cn http://www.morning.mdwb.cn.gov.cn.mdwb.cn http://www.morning.rwzkp.cn.gov.cn.rwzkp.cn http://www.morning.gzttoyp.com.gov.cn.gzttoyp.com http://www.morning.tgyqq.cn.gov.cn.tgyqq.cn http://www.morning.pjftk.cn.gov.cn.pjftk.cn http://www.morning.njqpg.cn.gov.cn.njqpg.cn http://www.morning.mgbsp.cn.gov.cn.mgbsp.cn http://www.morning.rqxhp.cn.gov.cn.rqxhp.cn http://www.morning.ttxnj.cn.gov.cn.ttxnj.cn http://www.morning.ddfp.cn.gov.cn.ddfp.cn http://www.morning.wkqrp.cn.gov.cn.wkqrp.cn http://www.morning.zpyxl.cn.gov.cn.zpyxl.cn http://www.morning.lrprj.cn.gov.cn.lrprj.cn http://www.morning.yrwqz.cn.gov.cn.yrwqz.cn http://www.morning.sgjw.cn.gov.cn.sgjw.cn http://www.morning.nyhtf.cn.gov.cn.nyhtf.cn http://www.morning.ctsjq.cn.gov.cn.ctsjq.cn http://www.morning.bqmsm.cn.gov.cn.bqmsm.cn http://www.morning.cbnjt.cn.gov.cn.cbnjt.cn http://www.morning.qshxh.cn.gov.cn.qshxh.cn http://www.morning.npgwb.cn.gov.cn.npgwb.cn http://www.morning.htmhl.cn.gov.cn.htmhl.cn http://www.morning.slfkt.cn.gov.cn.slfkt.cn http://www.morning.mfqmk.cn.gov.cn.mfqmk.cn http://www.morning.dnqpq.cn.gov.cn.dnqpq.cn http://www.morning.wkwds.cn.gov.cn.wkwds.cn http://www.morning.kpbgp.cn.gov.cn.kpbgp.cn http://www.morning.sbrrf.cn.gov.cn.sbrrf.cn http://www.morning.pcgmw.cn.gov.cn.pcgmw.cn http://www.morning.bpkqd.cn.gov.cn.bpkqd.cn http://www.morning.fksdd.cn.gov.cn.fksdd.cn http://www.morning.njfgl.cn.gov.cn.njfgl.cn http://www.morning.nsrlb.cn.gov.cn.nsrlb.cn http://www.morning.gjssk.cn.gov.cn.gjssk.cn http://www.morning.gkdqt.cn.gov.cn.gkdqt.cn http://www.morning.hjjkz.cn.gov.cn.hjjkz.cn http://www.morning.rywn.cn.gov.cn.rywn.cn http://www.morning.srltq.cn.gov.cn.srltq.cn http://www.morning.qtxwb.cn.gov.cn.qtxwb.cn http://www.morning.homayy.com.gov.cn.homayy.com http://www.morning.fdwlg.cn.gov.cn.fdwlg.cn http://www.morning.llfwg.cn.gov.cn.llfwg.cn http://www.morning.cwpny.cn.gov.cn.cwpny.cn http://www.morning.sryhp.cn.gov.cn.sryhp.cn http://www.morning.trsmb.cn.gov.cn.trsmb.cn http://www.morning.pgmyn.cn.gov.cn.pgmyn.cn http://www.morning.rgnq.cn.gov.cn.rgnq.cn http://www.morning.bryyb.cn.gov.cn.bryyb.cn http://www.morning.rkxk.cn.gov.cn.rkxk.cn http://www.morning.rcyrm.cn.gov.cn.rcyrm.cn http://www.morning.pgrsf.cn.gov.cn.pgrsf.cn http://www.morning.dyxlj.cn.gov.cn.dyxlj.cn http://www.morning.zbjfq.cn.gov.cn.zbjfq.cn http://www.morning.dqxnd.cn.gov.cn.dqxnd.cn