当前位置:  编程技术>软件工程/软件设计
本页文章导读:
    ▪学过DRP再看设计模式之 代理       引出问题(打印日志为例)程序运行应该记录运行日志信息,以作记录和分析。打印日志代码放在实现类UserManagerImp中UserManagerImpl.javapublic class UserManagerImpl implements UserManager { publicvoid addUser(S.........
    ▪关于SIGPIPE信号       我写了一个服务器程序,在Linux下测试,然后用C++写了客户端用千万级别数量的短链接进行压力测试.  但是服务器总是莫名退出,没有core文件. 最后问题确定为, 对一个对端已经关闭.........
    ▪第2章 XAML      xmlns特性是XML中的一个特殊标记,专门用于声明命名空间。 xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName" x:Class 告诉XAML解析器用指定的名称生成一个新类。 x:Name 告诉XAML解析器将一个.........

[1]学过DRP再看设计模式之 代理
    来源: 互联网  发布时间: 2013-11-19

引出问题(打印日志为例)

程序运行应该记录运行日志信息,以作记录和分析。

打印日志代码放在实现类UserManagerImp中

UserManagerImpl.java

public class UserManagerImpl implements UserManager {
 
publicvoid addUser(String userId, String userName) {
System.out.println("start-->>addUser()userId-->>" + userId);
try{
System.out.println("UserManagerImpl.addUser()userId-->>" + userId);
 
System.out.println("success-->>addUser()");
}catch(Exceptione) {
e.printStackTrace();
System.out.println("error-->>addUser()");
thrownew RuntimeException();
}        
}
}


 

 

可以看出:

需求变时需要改,对已经测试好的代码开放修改

但代码重复,工作量大,修改时恐怖

 

引入代理


代理模式是对象的结构型模式,给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用。

 

静态

代理对象在编译阶段被创建

打印日志代码抽出,放在UserManagerProxy


UserManagerImplProxy.java

publicclass UserManagerImplProxy implements UserManager {
 
privateUserManager userManager;
 
publicUserManagerImplProxy(UserManager userManager) {
this.userManager= userManager;
}
 
publicvoid addUser(String userId, String userName) {
try{
System.out.println("start-->>addUser()userId-->>" + userId);
userManager.addUser(userId,userName);
System.out.println("success-->>addUser()");
}catch(Exceptione) {
e.printStackTrace();
System.out.println("error-->>addUser()");
}        
}
}


 

第一个问题倒是解决了——关闭修改了。

但第二个问题——代码重复,工作量大,修改时恐怖,却没有得到解决。

 

 

动态

运行时创建的

打印日志代码放在LogHandler中


LogHandler.java

/**
 * 采用动态代理封装日志
 * @author TCH
 *
 */
publicclass LogHandler implements InvocationHandler {
 
privateObject targetObject;
 
publicObject newProxyInstance(Object targetObject) {
this.targetObject= targetObject;
returnProxy.newProxyInstance(targetObject.getClass().getClassLoader(),
   targetObject.getClass().getInterfaces(),this);
}
 
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
System.out.println("start-->>"+ method.getName());
for(int i=0; i<args.length; i++) {
System.out.println(args[i]);
}
Objectret = null;
try{
//调用目标方法
ret= method.invoke(targetObject, args);
System.out.println("success-->>"+ method.getName());
 
}catch(Exceptione) {
e.printStackTrace();
System.out.println("error-->>"+ method.getName());
 
//分析异常
if(e instanceof InvocationTargetException) {
InvocationTargetExceptionete = (InvocationTargetException)e;
throwete.getTargetException();
}
 
thrownew ApplicationException("调用目标方法" + method.getName() +" 失败!");
}
returnret;
}
}


 

 

  • 打印日志的代码可以被提炼出来,因为提供了独立服务,跟添加删除、具体逻辑等操作没关系,但又是公共部分,所以才能提炼出LogHandler。
  • 打印日志的代码只维护一份,省事多了,而且出问题几率大大降低。
  • JDK动态代理只能对实现了接口的类进行代理,采用JDK动态代理必须实现InvocationHandler接口,采用Proxy类创建相应的代理类。
  • InvocationTargetException包装自定义异常

在invoke方法中捕获异常,捕获到的自定义异常被包装在InvocationTargetException中的target属性中。

 

 

应用:使用动态代理封装事务,并在
    
[2]关于SIGPIPE信号
    来源: 互联网  发布时间: 2013-11-19

我写了一个服务器程序,在Linux下测试,然后用C++写了客户端用千万级别数量的短链接进行压力测试.  但是服务器总是莫名退出,没有core文件.
最后问题确定为, 对一个对端已经关闭的socket调用两次write, 第二次将会生成SIGPIPE信号, 该信号默认结束进程.
具体的分析可以结合TCP的"四次握手"关闭. TCP是全双工的信道, 可以看作两条单工信道, TCP连接两端的两个端点各负责一条. 当对端调用close时, 虽然本意是关闭整个两条信道, 但本端只是收到FIN包. 按照TCP协议的语义, 表示对端只是关闭了其所负责的那一条单工信道, 仍然可以继续接收数据. 也就是说, 因为TCP协议的限制, 一个端点无法获知对端的socket是调用了close还是shutdown.
对一个已经收到FIN包的socket调用read方法, 如果接收缓冲已空, 则返回0, 这就是常说的表示连接关闭. 但第一次对其调用write方法时, 如果发送缓冲没问题, 会返回正确写入(发送). 但发送的报文会导致对端发送RST报文, 因为对端的socket已经调用了close, 完全关闭, 既不发送, 也不接收数据. 所以, 第二次调用write方法(假设在收到RST之后), 会生成SIGPIPE信号, 导致进程退出.
为了避免进程退出, 可以捕获SIGPIPE信号, 或者忽略它, 给它设置SIG_IGN信号处理函数:
signal(SIGPIPE, SIG_IGN);
这样, 第二次调用write方法时, 会返回-1, 同时errno置为SIGPIPE. 程序便能知道对端已经关闭.


在linux下写socket的程序的时候,如果尝试send到一个disconnected socket上,就会让底层抛出一个SIGPIPE信号。
这个信号的缺省处理方法是退出进程,大多数时候这都不是我们期望的。因此我们需要重载这个信号的处理方法。调用以下代码,即可安全的屏蔽SIGPIPE:
signal (SIGPIPE, SIG_IGN);
我的程序产生这个信号的原因是: 
client端通过 pipe 发送信息到server端后,就关闭client端, 这时server端,返回信息给 client 端时就产生Broken pipe 信号了,服务器就会被系统结束了。


对于产生信号,我们可以在产生信号前利用方法 signal(int signum, sighandler_t handler) 设置信号的处理。如果没有调用此方法,系统就会调用默认处理方法:中止程序,显示提示信息(就是我们经常遇到的问题)。我们可以调用系统的处理方法,也可以自定义处理方法。 


系统里边定义了三种处理方法: 
(1)SIG_DFL信号专用的默认动作:
  (a)如果默认动作是暂停线程,则该线程的执行被暂时挂起。当线程暂停期间,发送给线程的任何附加信号都不交付,直到该线程开始执行,但是SIGKILL除外。
  (b)把挂起信号的信号动作设置成SIG_DFL,且其默认动作是忽略信号 (SIGCHLD)。
(2)SIG_IGN忽略信号
  (a)该信号的交付对线程没有影响
  (b)系统不允许把SIGKILL或SIGTOP信号的动作设置为SIG_DFL
3)SIG_ERR   


项目中我调用了signal(SIGPIPE, SIG_IGN), 这样产生  SIGPIPE 信号时就不会中止程序,直接把这个信号忽略掉。

作者:oSherryLee 发表于2013-5-14 10:24:10 原文链接
阅读:45 评论:0 查看评论

    
[3]第2章 XAML
    来源: 互联网  发布时间: 2013-11-19

xmlns特性是XML中的一个特殊标记,专门用于声明命名空间。

xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName"

x:Class 告诉XAML解析器用指定的名称生成一个新类。

x:Name 告诉XAML解析器将一个字段添加到Window类自动生成的部分(应该是*.g.cs或*.g.i.cs)

x:static 允许引用另一个类中的静态属性。

背景颜色渐变实现:

        <Grid.Background>
            <LinearGradientBrush EndPoint="0,0.5">
                <GradientStopCollection>
                    <GradientStop Color="#FF4B1282" Offset="0.2"/>
                    <GradientStop Color="#E78AAC7F" Offset="0.4"/>
                    <GradientStop Color="#FF6A009B" Offset="0.6"/>
                </GradientStopCollection>
            </LinearGradientBrush>
        </Grid.Background>

Content属性

如果希望在文本中包含一系列空格,需要为元素使用xml:space="preserve".

        <TextBox Grid.Column="1" Margin="2,2,2,2" xml:space="preserve">da          asd</TextBox>
        <!--等价于<TextBox Grid.Column="1" Margin="2,2,2,2" Text="da          asd">-->

TypeConverter类以及TypeConverter特性实现类型间的单向绑定。

作者:xufei96 发表于2013-5-14 15:41:06 原文链接
阅读:0 评论:0 查看评论

    
最新技术文章:
▪主-主数据库系统架构    ▪java.lang.UnsupportedClassVersionError: Bad version number i...    ▪eclipse项目出现红色叉叉解决方案
▪Play!framework 项目部署到Tomcat    ▪dedecms如何做中英文网站?    ▪Spring Batch Framework– introduction chapter(上)
▪第三章 AOP 基于@AspectJ的AOP    ▪基于插件的服务集成方式    ▪Online Coding开发模式 (通过在线配置实现一个表...
▪观察者模式(Observer)    ▪工厂模式 - 程序实现(java)    ▪几种web并行化编程实现
▪机器学习理论与实战(二)决策树    ▪Hibernate(四)——全面解析一对多关联映射    ▪我所理解的设计模式(C++实现)——解释器模...
▪利用规则引擎打造轻量级的面向服务编程模式...    ▪google blink的设计计划: Out-of-Progress iframes    ▪FS SIP呼叫的消息线程和状态机线程
▪XML FREESWITCH APPLICATION 实现    ▪Drupal 实战    ▪Blink: Chromium的新渲染引擎
▪(十四)桥接模式详解(都市异能版)    ▪你不知道的Eclipse用法:使用Allocation tracker跟...    ▪Linux内核-进程
▪你不知道的Eclipse用法:使用Metrics 测量复杂度    ▪IT行业为什么没有进度    ▪Exchange Server 2010/2013三种不同的故障转移
▪第二章 IoC Spring自动扫描和管理Bean    ▪CMMI简介    ▪目标检测(Object Detection)原理与实现(六)
▪值班总结(1)——探讨sql语句的执行机制    ▪第二章 IoC Annotation注入    ▪CentOS 6.4下安装Vagrant
▪Java NIO框架Netty1简单发送接受    ▪漫画研发之八:会吃的孩子有奶吃    ▪比较ASP和ASP.NET
▪SPRING中的CONTEXTLOADERLISTENER    ▪在Nginx下对网站进行密码保护    ▪Hibernate从入门到精通(五)一对一单向关联映...
▪.NET领域驱动设计—初尝(三:穿过迷雾走向光...    ▪linux下的块设备驱动(一)    ▪Modem项目工作总结
▪工作流--JBPM简介及开发环境搭建    ▪工作流--JBPM核心服务及表结构    ▪Eclipse:使用JDepend 进行依赖项检查
▪windows下用putty上传文件到远程Linux方法    ▪iBatis和Hibernate的5点区别    ▪基于学习的Indexing算法
▪设计模式11---设计模式之中介者模式(Mediator...    ▪带你走进EJB--JMS编程模型    ▪从抽象谈起(二):观察者模式与回调
▪设计模式09---设计模式之生成器模式(Builder)也...    ▪svn_resin_持续优化中    ▪Bitmap recycle方法与制作Bitmap的内存缓存
▪Hibernate从入门到精通(四)基本映射    ▪设计模式10---设计模式之原型模式(Prototype)    ▪Dreamer 3.0 支持json、xml、文件上传
▪Eclipse:使用PMD预先检测错误    ▪Jspx.net Framework 5.1 发布    ▪从抽象谈起(一):工厂模式与策略模式
▪Eclipse:使用CheckStyle实施编码标准    ▪【论文阅读】《Chain Replication for Supporting High T...    ▪Struts2 Path_路径问题
▪spring 配置文件详解    ▪Struts2第一个工程helloStruts极其基本配置    ▪Python学习入门基础教程(learning Python)--2 Python简...
▪maven springmvc环境配置    ▪基于SCRUM的金融软件开发项目    ▪software quality assurance 常见问题收录
▪Redis集群明细文档    ▪Dreamer 框架 比Struts2 更加灵活    ▪Maven POM入门
▪git 分支篇-----不断更新中    ▪Oracle非主键自增长    ▪php设计模式——UML类图
▪Matlab,Visio等生成的图片的字体嵌入问题解决...    ▪用Darwin和live555实现的直播框架    ▪学习ORM框架—hibernate(二):由hibernate接口谈...
▪(十)装饰器模式详解(与IO不解的情缘)    ▪无锁编程:最简单例子    ▪【虚拟化实战】网络设计之四Teaming
▪OSGi:生命周期层    ▪Javascript/Jquery——简单定时器    ▪java代码 发送GET、POST请求
▪Entity Framework底层操作封装(3)    ▪HttpClient 发送GET、POST请求    ▪使用spring框架,应用启动时,加载数据
▪Linux下Apache网站目录读写权限的设置    ▪单键模式的C++描述    ▪学习ORM框架—hibernate(一):初识hibernate
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3