JavaScript must be enabled in order for you to view this page. However, it seems JavaScript is either disabled or not supported by your browser. To view this page, enable JavaScript by changing your browser options, then Try again! .

 
我的论坛
Google 网上论坛 Beta 版
Do Best Developer
访问此论坛

Grady Booch的原话

A focus on building crisp abstractions, having a good separation of concerns, having a balanced distribution of responsibilities, and a fierce drive toward simplicity. Those things are at the heart of both OO and building good architectures, with or without the use of services.

这是Grady Booch的原话。我想大师就是大师,人家一语就道出了OO和构建良好架构的核心。

感谢我的朋友们

谢谢大家!

今天我读到了一位朋友sudianbo84的邮件,照抄如下:

Dear Mr solol,
I am sorry to send this email to bother you due to my stupidity,however ,I really need your help . 
Imitating the  main() method provided by yours JNIRegistry Package  , I wrote a program to modify 
the Internet Explore's settings in the windows' Registry ; but with something  wrong when I run my 
program,I hope you can give me some  help or advices! the following is the hints when my program runs
 
"com.ice.jni.registry.RegistryException: Registry API Error 5, 'access denied' - 'RegSetValueEx()'
  at com.ice.jni.registry.RegistryKey.setValue(Native Method)
  at org.solol.test.ssss.main(ssss.java:29)
com.ice.jni.registry.NoSuchValueException: RegQueryValueEx(), value='ProxyServer'
  at com.ice.jni.registry.RegistryKey.getStringValue(Native Method)
  at org.solol.test.ssss.main(ssss.java:47)
Press any key to continue..."
 
And this Is my program list:(I hope you can give me some  help or advices! )
 
package org.solol.test;
import com.ice.jni.registry.NoSuchKeyException;
import com.ice.jni.registry.RegStringValue;
import com.ice.jni.registry.RegDWordValue;
import com.ice.jni.registry.Registry;
import com.ice.jni.registry.RegistryException;
import com.ice.jni.registry.RegistryKey;
import com.ice.jni.registry.RegistryValue;
/**
 * @author solo L
 *
 */
public class ssss {
  /**
   * @param args
   */
  public static void main(String[] args) {
    try {
      RegistryKey IEsetting = Registry.HKEY_CURRENT_USER.openSubKey("Software").openSubKey("Microsoft").openSubKey("Windows").openSubKey("CurrentVersion").openSubKey("Internet Settings");
      IEsetting.setValue("ProxyServer", new RegStringValue(IEsetting,"ProxyServer","127.0.0.1:8080"));
      IEsetting.setValue(new RegDWordValue(IEsetting,"ProxyEnable",	RegistryValue.REG_DWORD,1)); 
      
      IEsetting.closeKey();
    } catch (NoSuchKeyException e) {
      e.printStackTrace();
    } catch (RegistryException e) {
      e.printStackTrace();
    }

    try {
      RegistryKey IEsetting = Registry.HKEY_CURRENT_USER.openSubKey("Software").openSubKey("Microsoft").openSubKey("Windows").openSubKey("CurrentVersion").openSubKey("Internet Settings");
      //RegistryKey IEsetting = software.openSubKey("SubKeyName");
      RegistryValue proxyenable = IEsetting.getValue("ProxyEnable");
      String proxyserver = IEsetting.getStringValue("ProxyServer");
      System.out.println(proxyenable.toString());
      System.out.println(proxyserver);
      IEsetting.closeKey();
    } catch (NoSuchKeyException e) {
      e.printStackTrace();
    } catch (RegistryException e) {
      e.printStackTrace();
    }   
  }
}	

这是由于我在文章用Java操作Windows注册表中犯了一个错误。

出错内容为:

  RegistryKey openSubKey(java.lang.String subkey) 打开该key的subkey,具有写权限。 

应该为:

  RegistryKey openSubKey(java.lang.String subkey) 打开该key的subkey,具有读权限。 

我已经对文章进行了更新。

sudianbo84朋友要解决你的问题可以使用下面的代码:

  RegistryKey currentVersion = Registry.HKEY_CURRENT_USER.openSubKey("Software").openSubKey("Microsoft").openSubKey("Windows").openSubKey("CurrentVersion");
  RegistryKey inetSetting = currentVersion.openSubKey("Internet Settings",RegistryKey.ACCESS_WRITE);
  inetSetting.setValue(new RegStringValue(inetSetting, "ProxyServer", "127.0.0.1:8080"));
  inetSetting.setValue(new RegDWordValue(inetSetting, "ProxyEnable",RegistryValue.REG_DWORD, 1));

再次感谢大家!谢谢!

差异

今天,眼睛接收文字的速度快过大脑好多倍。

如下的图片和两段文字源于IBM中国,可参见Architecture 新手入门

Complex System Design Diagram

之所以采取这种方式构建系统,是因为没有对它们进行很好的规划。它们通常由缺乏必备技能和资源的人匆忙地构建以满足即时之需,而没有考虑到长期成功所必需的质量。构建此类系统的团队要么是人员太少,要么就是人员太多,从而减弱而不是增强了最有才能的团队成员的影响。

从上图可以看出,在团队开始构建系统之前,必须进行体系结构设计。在构建系统时,需要由少数(或许就是一个)预言家来领导设计团队以避免此类大杂烩。该预言家的头脑中必须有一个全盘计划,而不是每一个具体细节,更多的是有关需要什么以及如何实现的总体思想。并由该预言家来负责系统的体系结构。在开始构建系统之前有了这样的预言家,并且已经有一个准备好的体系结构,就可以井然有序地构建一致、可理解的系统——在新需求出现时可由该团队或其他团队修改的系统。

我们不是上面所提到的预言家,至少目前不是,不过我们需要被一个这样的预言家领导。

Tomcat中的TCP Server

PoolTcpEndpoint是Tomcat中的TCP Server。主要负责:

  • 线程管理
  • 接收Socket连接
  • 调用ConnectionHandler

PoolTcpEndpoint代码可能不容易读懂,因为这里有两个并发模型的实现。一个是Leader Follower Worker模型,一个是Master Slave Worker模型。前者的线程管理由ThreadPool来完成的,而后者的线程管理是在PoolTcpEndpoint中完成的。两者共同使用在PoolTcpEndpoint中定义的接收Socket逻辑和调用ConnectionHandler逻辑。

PoolTcpEndpoint作为TCP Server只负责处理TCP连接。更加进一步的处理,如相关协议的解析等,由ProtocolHangler和Processor完成。最后由Adapter将处理代理给Container。

PoolTcpEndpoint是Tomcat的核心机构。

Tomcat中的策略模式

这个标题可能不是很确切。确切的说法应该是Commons Digester中的策略模式。

Commons Digester是Apache Jakarta的一个XML到Java Object的映射工具包。

Tomcat和Struts都使用这个工具包来处理XML配置文件。在Tomcat中并没有直接使用Digester的*.jar文件而是将Digester做了一些简化放到了org.apache.tomcat.util.digester包中。我们下面的讨论是基于org.apache.tomcat.util.digester包的,这也是我们使用这个标题的用意,但是这里的讨论也完全适用于Digester。

具体的结构图如下:

Tomcat中的策略模式

这里涉及到两个策略模式。Rules是一个策略,封装了选择Rule的逻辑,可以通过定制Rules来实现自定义匹配逻辑。Rule是另一个策略,这是显而易见,封装了某种操作。如果需要自定义Rule那么必须认真考虑相关堆栈的状态。通常的做法是谁改变谁负责恢复。

关于模式的相关问题可以参阅面向对象设计(Object-Oriented Design)。如果您对这里的内容感兴趣可以和我们联系!

置于文件系统之外的web应用程序

今天的话题非常有趣!这和当初读Java VM规范中关于Class Loader部分时的感觉一样。如果需要可以将Java Class放到数据库中或网络上,等等,当然还可以想到更多 ... ,只是不放到文件系统中。如果没有需要就不要这么做,否则会很无聊。

该话题源于这里The Resources Component

通常使用tomcat只需要把web应用程序拷贝到$CATALINA_HOME/webapps目录下,此时web应用程序是以文件的形式存在于文件系统之中。我们对此已经习以为常了,然而tomcat还允许使用其它的方式:

  • 将web应用程序置于压缩的war文件中
  • 将web应用程序置于jar文件中
  • 将web应用程序置于zip文件中
  • ... ... 其它的一些流行的压缩格式
  • 将web应用程序置于数据库中
  • 将web应用程序置于版本库中
  • 将web应用程序置于自定义的格式中
  • ... ... 肯定还有很多

如果您要对相关web应用程序进行加密,这里也提供了一种可行的方法。例如可以将web应用中的每一个文件加密后压缩到一个zip文件中,也可以先将整个web应用置于zip文件中在对zip文件加密。

要完成上面描述的内容,需要自己实现javax.naming.directory.DirContext接口。在此之前可能需要仔细研究一下tomcat提供的一些实现,如FileDirContext和WARDirContext等。

这个话题中的内容是tomcat相关的,如果您不使用tomcat,那么您需要仔细查阅您的web服务器的文档。

最后,我们必须告诉大家:我们没有实现过上面描述的内容,因此也不知道将会遇到什么样的困难。这里只是描述一种可能。

Tomcat中的观察者模式 二

在上一篇中我们谈到了Tomcat中的观察者模式,这里标题中的“二”并不表示我们要继续上一篇的相关内容,仅仅表示我们要讨论Tomcat中的另外一个观察者模式。

上一篇中的观察者模式用来报告生命周期事件(Lifecycle Event),这里的这个观察者模式用来报告容器事件(Container Event),这两者是完全不同的。

具体的结构图如下:

Tomcat中的观察者模式 二

和上一篇相比这里和GoF的描述是完全一致的,由Subject参与者负责管理Observer参与者。不过这里也实现了复用,这种复用是通过继承完成的。所有的管理逻辑都在ContainerBase。

关于模式的相关问题可以参阅面向对象设计(Object-Oriented Design)。如果您对这里的内容感兴趣可以和我们联系!

Tomcat中的观察者模式

观察者模式擅长进行对象生命周期的管理。

Tomcat需要对Server、Service、Engine、Host和Context等进行生命周期的管理。这种管理是通过Lifecycle(Subject)、LifecycleListener(Observer)和LifecycleEvent来实施的。

具体的结构图如下:

Tomcat中的观察者模式

在GoF给出的观察者模式中要由Subject参与者负责管理Observer参与者,这里也不例外。只不过Subject参与者的管理职责被委托给了LifecycleSupport而由后者负责具体的实现。这样多种Subject可以复用LifecycleSupport。

关于模式的相关问题可以参阅面向对象设计(Object-Oriented Design)。如果您对这里的内容感兴趣可以和我们联系!

Tomcat中的职责链模式

职责链模式在Tomcat中用来处理请求(Request)和响应(Response)。该模式出现在Tomcat的四个Container中,它们是:

  • org.apache.catalina.core.StandardEngine
  • org.apache.catalina.core.StandardHost
  • org.apache.catalina.core.StandardContext
  • org.apache.catalina.core.StandardWrapper

下面我们给出具体的结构图:

Tomcat中的职责链模式

值得注意的是,和GoF给出的职责链模式的描述相比,这里多出了一个参与者Pipeline,它主要负责整个职责链的管理。从客户的角度来讲,这是非常有益的,因为客户不必在自行维护整条职责链。如果有多种客户在使用相同的职责链这种益处就更加明显。

关于模式的相关问题可以参阅这里[ http://www.solol.org/technologic/ood/ ]。这里的内容还只是在有限的范围内发布,没有放到公共域中,因为绝大多数内容还没有完成。如果您对这里的内容感兴趣可以和我们联系!