研磨设计模式之——代理模式(一)

案例:

  在一个项目中客户提出,选择一个部门或者分公司时,要把这个部门或者分公司的所有员工显示出来,而不要翻页。在现实员工时,只需要显示

名称即可,但是也需要提供查看员工详细信息。

  • 不用模式的解决方案

   用sql语句查询改分公司下的所有员工信息。我们使用jdbc模拟,底层数据库为mysql

  sql脚本如下:

 1 SET FOREIGN_KEY_CHECKS=0;
 2
 3 -- ----------------------------
 4 -- Table structure for tbl_dep
 5 -- ----------------------------
 6 DROP TABLE IF EXISTS `tbl_dep`;
 7 CREATE TABLE `tbl_dep` (
 8   `depId` varchar(20) NOT NULL,
 9   `name` varchar(20) DEFAULT NULL,
10   PRIMARY KEY (`depId`)
11 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
12
13 -- ----------------------------
14 -- Records of tbl_dep
15 -- ----------------------------
16 INSERT INTO `tbl_dep` VALUES (‘01‘, ‘总公司‘);
17 INSERT INTO `tbl_dep` VALUES (‘0101‘, ‘一分公司‘);
18 INSERT INTO `tbl_dep` VALUES (‘010101‘, ‘开发部‘);
19 INSERT INTO `tbl_dep` VALUES (‘010102‘, ‘测试部‘);
20 INSERT INTO `tbl_dep` VALUES (‘0102‘, ‘二分公司‘);
21 INSERT INTO `tbl_dep` VALUES (‘010201‘, ‘开发部‘);
22 INSERT INTO `tbl_dep` VALUES (‘010202‘, ‘测试部‘);
23
24 -- ----------------------------
25 -- Table structure for tbl_user
26 -- ----------------------------
27 DROP TABLE IF EXISTS `tbl_user`;
28 CREATE TABLE `tbl_user` (
29   `userId` varchar(20) NOT NULL,
30   `name` varchar(20) DEFAULT NULL,
31   `depId` varchar(20) NOT NULL,
32   `sex` varchar(10) DEFAULT NULL,
33   PRIMARY KEY (`userId`),
34   KEY `TBL_USER_FK` (`depId`),
35   CONSTRAINT `TBL_USER_FK` FOREIGN KEY (`depId`) REFERENCES `tbl_dep` (`depId`)
36 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
37
38 -- ----------------------------
39 -- Records of tbl_user
40 -- ----------------------------
41 INSERT INTO `tbl_user` VALUES (‘user0001‘, ‘张三1‘, ‘010101‘, ‘男‘);
42 INSERT INTO `tbl_user` VALUES (‘user0002‘, ‘张三2‘, ‘010101‘, ‘男‘);
43 INSERT INTO `tbl_user` VALUES (‘user0003‘, ‘张三3‘, ‘010102‘, ‘男‘);
44 INSERT INTO `tbl_user` VALUES (‘user0004‘, ‘张三4‘, ‘010201‘, ‘男‘);
45 INSERT INTO `tbl_user` VALUES (‘user0005‘, ‘张三5‘, ‘010201‘, ‘男‘);
46 INSERT INTO `tbl_user` VALUES (‘user0006‘, ‘张三6‘, ‘010202‘, ‘男‘);
47 SET FOREIGN_KEY_CHECKS=1;

用户数据对象为:

 1 package com.huang;
 2
 3 /**
 4  * Created by huangyichun on 2016/12/8.
 5  */
 6 public class UserModel {
 7
 8     private String userId;
 9
10     private String userName;
11     private String depId;
12     private String sex;
13
14     public String getUserId() {
15         return userId;
16     }
17
18     public void setUserId(String userId) {
19         this.userId = userId;
20     }
21
22     public String getUserName() {
23         return userName;
24     }
25
26     public void setUserName(String userName) {
27         this.userName = userName;
28     }
29
30     public String getDepId() {
31         return depId;
32     }
33
34     public void setDepId(String depId) {
35         this.depId = depId;
36     }
37
38     public String getSex() {
39         return sex;
40     }
41
42     public void setSex(String sex) {
43         this.sex = sex;
44     }
45
46     @Override
47     public String toString() {
48         return "UserModel{" +
49                 "userId=‘" + userId + ‘\‘‘ +
50                 ", userName=‘" + userName + ‘\‘‘ +
51                 ", depId=‘" + depId + ‘\‘‘ +
52                 ", sex=‘" + sex + ‘\‘‘ +
53                 ‘}‘;
54     }
55 }

Jdbc实现功能

package com.huang;

import java.sql.*;
import java.util.ArrayList;
import java.util.Collection;

/**
 * Created by huangyichun on 2016/12/8.
 */
public class UserManager {

    public Collection<UserModel> getUserByDepId(String depId){

        Collection<UserModel> col = new ArrayList<UserModel>();
        Connection conn = null;
        try {
            conn = this.getConnection();
            String sql = "select * from tbl_user u, tbl_dep d " +
                    "where u.depId=d.depId and d.depId like ?";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            preparedStatement.setString(1,depId + "%");

            ResultSet rs = preparedStatement.executeQuery();
            while(rs.next()){
                UserModel um = new UserModel();
                um.setUserId(rs.getString("userId"));
                um.setUserName(rs.getString("name"));
                um.setDepId(rs.getString("depId"));
                um.setSex(rs.getString("sex"));

                col.add(um);
            }
            rs.close();
            preparedStatement.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return col;
    }

    private Connection getConnection() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root",//改成自己的账号密码
                "root");
    }
}

测试类:

package com.huang;

import java.util.Collection;

/**
 * Created by huangyichun on 2016/12/8.
 */
public class Client {

    public static void main(String[] args){
        UserManager userManager = new UserManager();
        Collection<UserModel> col = userManager.getUserByDepId("0101");
        System.out.println(col);
    }
}

输出结果:

[UserModel{userId=‘user0001‘, userName=‘张三1‘, depId=‘010101‘, sex=‘男‘},

UserModel{userId=‘user0002‘, userName=‘张三2‘, depId=‘010101‘, sex=‘男‘},

UserModel{userId=‘user0003‘, userName=‘张三3‘, depId=‘010102‘, sex=‘男‘}]

使用代理模式解决问题 

  1.代理模式的定义

    为其他对象提供一种代理以控制对这个对象的访问

  2. 代理模式解决思路

    代理模式引入一个Proxy对象来解决这个问题。刚开始只有用户编号和姓名的时候,不是一个完整的用户对象,而是一个代理对象。当需要访问

  完整的用户数据的时候,代理会从数据库中重新获取相应的数据,通常情况下是当客户需要访问除了用户编号和姓名之外的数据的时候,代理才会重新

  去获取数据。

  3.代理模式的结构和说明(图片是别人的)

      

  4.代理模式的示例代码

  

package com.huang.proxy;

/**
 * 抽象的目标接口,定义具体的目标对象和代理公用的接口
 */
public interface Subject {
    /**
     * 示意方法:一个抽象的请求方法
     */
     void request();
}
package com.huang.proxy;

/**
 * 具体的目标对象,是真正被代理的对象
 */
public class RealSubject implements Subject {

    public void request() {
        //执行具体的功能处理
    }
}
package com.huang.proxy;

/**
 * 代理对象
 */
public class Proxy implements Subject {
    /**
     * 持有被代理的具体的目标对象
     */
    private RealSubject realSubject = null;

    /**
     * 构造方法,传入被代理的具体的目标对象
     * @param realSubject
     */
    public Proxy(RealSubject realSubject){
        this.realSubject = realSubject;
    }

    public void request() {
        //在转调具体的目标对象前,可以执行一些功能的处理

        //转调具体的目标对象的方法
        realSubject.request();

        //在转调具体的目标对象方法后,可以执行一些功能的处理
    }
}

下一篇讲述使用代理模式重写示例。

时间: 2024-10-21 00:39:53

研磨设计模式之——代理模式(一)的相关文章

Android设计模式之代理模式 Proxy

一.概述 代理模式也是平时比较常用的设计模式之一,代理模式其实就是提供了一个新的对象,实现了对真实对象的操作,或成为真实对象的替身.在日常生活中也是很常见的.例如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A坐享中介筛选的结果,并且交房租也是交给中介,这就是一个典型的日常生活中代理模式的应用.平时打开网页,最先开到的一般都是文字,而图片等一些大的资源都会延迟加载,这里也是使用了代理模式. 代理模式的组成: Abstract Subject:抽象主题-声明真实主题和代理主题共同的接口

【设计模式】代理模式

代理模式在所需对象和用户代码之间增加了一层对象,这个对象被称为代理.用户代码只需要直接操作代理对象即可.著名的代理模式的例子就是引用计数指针对象,它使得我们对真实对象的操作都需要经过引用计数指针对象.下面是用C++写的一个运用了代理模式的例子. #include <iostream> #include <string> using namespace std; // 作为接口的抽象基类 class Subject { public: virtual void DoAction()

设计模式之代理模式(Proxy)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

【大话设计模式】——代理模式

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到. Hibernate支持三种继承映射策略: 使用 subclass 进行映射:将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态. 使用 joined-subclass 进行映射: 对于继承关系中的子类使用同一个表

设计模式之代理模式 c++实现以及详解

proxy模式 <1> 作用: 为其他对象提供一种代理以控制对这个对象的访问. <2> 代理模式的应用场景: 如果已有的方法在使用的时候需要对原有的方法进行改进,此时有两种办法: 1.修改原有的方法来适应.这样违反了"对扩展开放,对修改关闭"的原则. 2.就是采用一个代理类调用原有的方法,且对产生的结果进行控制.这种方法就是代理模式. 使用代理模式,可以将功能划分的更加清晰,有助于后期维护! <3> 结构图 代理类,含有一个指向RealSubject

JAVA设计模式之代理模式

学编程吧JAVA设计模式之代理模式发布了,欢迎通过xuebiancheng8.com来访问 一.概述 给某一个对象提供一个代理,并由代理对象来完成对原对象的访问.代理模式是一种对象结构型模式. 二.适用场景 当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口. 三.UML类图 四.参与者 1.接口类:Subject 它声明了真实访问者和代理访问者的共同接口,客户端通常需要针对接口角色进行编程. 2.代理类

JAVA设计模式(3)----代理模式

1.  什么是代理模式?Proxy Pattern 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 通俗的讲,代理模式就是我很忙没空理你,你要想找我可以先找我的代理人,代理人和被代理人继承同一个接口.代理人虽然不能干活,但是被代理的人可以干活. 这个例子中有水浒传中的这么几个人:名垂青史的潘金莲,王婆,西门大官人.西门庆想要找潘金莲,需要找王婆做代理.首先定义一个接口:Kin

设计模式之代理模式20170724

结构型设计模式之代理模式: 一.含义 代理模式也叫做委托模式,其定义如下: 为其他对象提供一种代理以控制对这个对象的访问. 二.代码说明 1.主要有两个角色 1)具体主题角色 也叫做委托角色.被代理角色.它是业务逻辑的具体执行者. 2)代理主题角色 也叫做委托类.代理类.它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作. 一个代理类可以代理多个被委托者或被代理者. 2.在用C实现过程中也是参考这种思想,以游戏代理场

设计模式 11 —— 代理模式

设计模式目录: 设计模式 1 ——观察者模式 设计模式 2 —— 装饰者模式 设计模式 3 —— 迭代器和组合模式(迭代器) 设计模式 4 —— 迭代器和组合模式(组合) 设计模式 5 —— 工厂模式 设计模式 6 —— 单件模式 设计模式 7 —— 命令模式 设计模式 8 —— 适配器和外观模式 设计模式 9 —— 模板方法模式 设计模式 10 —— 状态模式 设计模式 11 —— 代理模式 概述 一 代理模式基本概念 二 参考 一 代理模式基本概念 代理模式为另一个对象提供一个替身或占位符以