Pages

Saturday, March 31, 2012

Design Pattern: Factory


from: http://www.jdon.com/designpatterns/designpattern_factory.htm

工厂模式定义:提供创建对象的接口.
为何使用?
工厂模式是我们最常用的模式了,著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。
为什么工厂模式是如此常用?因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑实用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。
我们以类Sample为例, 如果我们要创建Sample的实例对象:
Sample sample=new Sample();
可是,实际情况是,通常我们都要在创建sample实例时做点初始化的工作,比如赋值 查询数据库等。
首先,我们想到的是,可以使用Sample的构造函数,这样生成实例就写成:
Sample sample=new Sample(参数);
但是,如果创建sample实例时所做的初始化工作不是象赋值这样简单的事,可能是很长一段代码,如果也写入构造函数中,那你的代码很难看了(就需要Refactor重整)。
为什么说代码很难看,初学者可能没有这种感觉,我们分析如下,初始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有背于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派"切割"成每段,将每段再"封装"起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。
在本例中,首先,我们需要将创建实例的工作与使用实例的工作分开, 也就是说,让创建实例所需要的大量初始化工作从Sample的构造函数中分离出去。
这时我们就需要Factory工厂模式来生成对象了,不能再用上面简单new Sample(参数)。还有,如果Sample有个继承如MySample, 按照面向接口编程,我们需要将Sample抽象成一个接口.现在Sample是接口,有两个子类MySample 和HisSample .我们要实例化他们时,如下:
Sample mysample=new MySample();
Sample hissample=new HisSample();
随着项目的深入,Sample可能还会"生出很多儿子出来", 那么我们要对这些儿子一个个实例化,更糟糕的是,可能还要对以前的代码进行修改:加入后来生出儿子的实例.这在传统程序中是无法避免的.
但如果你一开始就有意识使用了工厂模式,这些麻烦就没有了.
工厂方法你会建立一个专门生产Sample实例的工厂:
public class Factory{
  public static Sample creator(int which){
  //getClass 产生Sample 一般可使用动态类装载装入类。
  if (which==1)
    return new SampleA();
  else if (which==2)
    return new SampleB();

  }
}
那么在你的程序中,如果要实例化Sample时.就使用
Sample sampleA=Factory.creator(1);
这样,在整个就不涉及到Sample的具体子类,达到封装效果,也就减少错误修改的机会,这个原理可以用很通俗的话来比喻:就是具体事情做得越多,越容易范错误.这每个做过具体工作的人都深有体会,相反,官做得越高,说出的话越抽象越笼统,范错误可能性就越少.好象我们从编程序中也能悟出人生道理?呵呵.
使用工厂方法 要注意几个角色,首先你要定义产品接口,如上面的Sample,产品接口下有Sample接口的实现类,如SampleA,其次要有一个factory类,用来生成产品Sample,如下图,最右边是生产的对象Sample:
进一步稍微复杂一点,就是在工厂类上进行拓展,工厂类也有继承它的实现类concreteFactory了
抽象工厂
工厂模式中有: 工厂方法(Factory Method) 抽象工厂(Abstract Factory).
这两个模式区别在于需要创建对象的复杂程度上。如果我们创建对象的方法变得复杂了,如上面工厂方法中是创建一个对象Sample,如果我们还有新的产品接口Sample2.
这里假设:Sample有两个concrete类SampleA和SamleB,而Sample2也有两个concrete类Sample2A和SampleB2
那么,我们就将上例中Factory变成抽象类,将共同部分封装在抽象类中,不同部分使用子类实现,下面就是将上例中的Factory拓展成抽象工厂:
public abstract class Factory{
  public abstract Sample creator();
  public abstract Sample2 creator(String name);
}
public class SimpleFactory extends Factory{
  public Sample creator(){
    .........
    return new SampleA

  }

  public Sample2 creator(String name){
    .........
    return new Sample2A

  }

}
public class BombFactory extends Factory{
  public Sample creator(){
    ......
    return new SampleB

  }

  public Sample2 creator(String name){
    ......
    return new Sample2B
  }

}
从上面看到两个工厂各自生产出一套Sample和Sample2,也许你会疑问,为什么我不可以使用两个工厂方法来分别生产Sample和Sample2?
抽象工厂还有另外一个关键要点,是因为 SimpleFactory内,生产Sample和生产Sample2的方法之间有一定联系,所以才要将这两个方法捆绑在一个类中,这个工厂类有其本身特征,也许制造过程是统一的,比如:制造工艺比较简单,所以名称叫SimpleFactory。
在实际应用中,工厂方法用得比较多一些,而且是和动态类装入器组合在一起应用。

我们以Jive的ForumFactory为例,这个例子在前面的Singleton模式中我们讨论过,现在再讨论其工厂模式:举例
public abstract class ForumFactory {
  private static Object initLock = new Object();
  private static String className = "com.jivesoftware.forum.database.DbForumFactory";
  private static ForumFactory factory = null;

  public static ForumFactory getInstance(Authorization authorization) {
    //If no valid authorization passed in, return null.
    if (authorization == null) {
      return null;
    }
    //以下使用了Singleton 单态模式
    if (factory == null) {
      synchronized(initLock) {
        if (factory == null) {
            ......

          try {
              //动态转载类
              Class c = Class.forName(className);
              factory = (ForumFactory)c.newInstance();
          }
          catch (Exception e) {
              return null;
          }
        }
      }
    }

    //Now, 返回 proxy.用来限制授权对forum的访问
    return new ForumFactoryProxy(authorization, factory,
                    factory.getPermissions(authorization));
  }

  //真正创建forum的方法由继承forumfactory的子类去完成.
  public abstract Forum createForum(String name, String description)
  throws UnauthorizedException, ForumAlreadyExistsException;

  ....
}

因为现在的Jive是通过数据库系统存放论坛帖子等内容数据,如果希望更改为通过文件系统实现,这个工厂方法ForumFactory就提供了提供动态接口:
private static String className = "com.jivesoftware.forum.database.DbForumFactory";
你可以使用自己开发的创建forum的方法代替com.jivesoftware.forum.database.DbForumFactory就可以.
在上面的一段代码中一共用了三种模式,除了工厂模式外,还有Singleton单态模式,以及proxy模式,proxy模式主要用来授权用户对forum的访问,因为访问forum有两种人:一个是注册用户 一个是游客guest,那么那么相应的权限就不一样,而且这个权限是贯穿整个系统的,因此建立一个proxy,类似网关的概念,可以很好的达到这个效果.  
看看Java宠物店中的CatalogDAOFactory:
public class CatalogDAOFactory {
  /**
  * 本方法制定一个特别的子类来实现DAO模式。
  * 具体子类定义是在J2EE的部署描述器中。
  */
  public static CatalogDAO getDAO() throws CatalogDAOSysException {
    CatalogDAO catDao = null;
    try {
      InitialContext ic = new InitialContext();
      //动态装入CATALOG_DAO_CLASS
      //可以定义自己的CATALOG_DAO_CLASS,从而在无需变更太多代码
      //的前提下,完成系统的巨大变更。
      String className =(String) ic.lookup(JNDINames.CATALOG_DAO_CLASS);
      catDao = (CatalogDAO) Class.forName(className).newInstance();
    } catch (NamingException ne) {
      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: NamingException while
          getting DAO type : \n" + ne.getMessage());
    } catch (Exception se) {
      throw new CatalogDAOSysException("
        CatalogDAOFactory.getDAO: Exception while getting
          DAO type : \n" + se.getMessage());
    }
    return catDao;
  }
}
CatalogDAOFactory是典型的工厂方法,catDao是通过动态类装入器className获得CatalogDAOFactory具体实现子类,这个实现子类在Java宠物店是用来操作catalog数据库,用户可以根据数据库的类型不同,定制自己的具体实现子类,将自己的子类名给与CATALOG_DAO_CLASS变量就可以。
由此可见,工厂方法确实为系统结构提供了非常灵活强大的动态扩展机制,只要我们更换一下具体的工厂方法,系统其他地方无需一点变换,就有可能将系统功能进行改头换面的变化。
设计模式如何在具体项目中应用见《Java实用系统开发指南》

Friday, March 30, 2012

tomcat发布失败(Could not delete May be locked by another process)


环境:eclipse tomcat
之前使用没有什么问题但是突然项目修改jsp文件后,tomcat不能发布,
Publishing failed with multiple errors
  Could not delete D:\Tomcat 6.0\webapps\Server\WEB-INF\platform\configuration\org.eclipse.core.runtime\.manager\.tmp1900396474661591532.instance. c.
  Could not delete D:\Tomcat 6.0\webapps\Server\WEB-INF\platform\configuration\org.eclipse.core.runtime\.manager\.tmp1907896664996379798.instance. May be locked by another process.
  Could not delete D:\Tomcat 6.0\webapps\Server\WEB-INF\platform\configuration\org.eclipse.equinox.app\.manager\.tmp2761653564891974481.instance. May be locked by another process.
 
网上找了两种解决办法
1.原文:
I was getting the annoying error in Eclipse with Tomcat where it didn’t think it could publish an application since some files were locked, when they were locked by the javaw.exe process that eclipse.exe started. The fix for me was to not have “Use Tomcat installation” selected in my server configuration. When I switched back to the default of “Use workspace metadata”, the error stopped happening.
[http://byprogrammerforprogrammer.com/2009/12/eclipsetomcat-publishing-lockup-could-not-delete-file-may-be-locked-by-another-process/]

 修改项目的发布地址
 
不过这个办法在我机器上没有起作用,我又发现了另一种方法
 
2.原文
 I performed a "clean" operation on the Tomcat server instance and the problem just went away. It's being doing fine since that. I'll let you know if I see this issue again.
[http://forums.adobe.com/message/2457298?tstart=0](3楼: )
 
 
 
 
我使用这种方法时,问题刚开始消失了,但过了一阵又是老样子。
 
我突然想到同一个eclipse下的别的项目使用的时候没有出现这个问题,有可能是项目设置的问题,
这个web项目引用了另外一个java项目(项目B),两个项目有一些相同的jar包,是不是这些相同的jar发布的问题呢,我把项目B的 Java EE Module Dependencies(项目B右键->Properties->Java EE Module Dependencies)里的jar包引用去掉,问题解决了。
 

Monday, March 26, 2012

The developer's guide to new exciting web technologies


from: http://www.netmagazine.com/features/developers-guide-new-exciting-web-technologies

Bruce Lawson, open web standards evangelist for Opera, looks at some nifty new browser technologies that are not part of HTML5, including WebGL and SVG

Recently, Rich Clark, my fellow HTML5 Doctor, took you on a short tour of HTML5 APIs and, before signing off, pointed you towards a bewildering page called The Web platform: Browser technologies containing two long columns of small text saying scary things like "window.crypto.getRandomValues" and "DOM mutation observers".
Don't worry, we're not going to look at all of those: some are so far from being finalised that it'll be a while before we see them in browsers. But some are already in browsers near you, or coming soon. People will call them "HTML5". They're not. But they are NEWT (New Exciting Web Technologies) that you should be keeping half an eye on.

WebGL

WebGL stands for Web-based Graphics Library, and is managed by the non-profit Khronos Group. It's used in conjunction with the HTML5 <canvas> element to produce 3D graphics.
WebGL is hard to learn, because it's very low-level – it runs on Graphics Processing Units – and because it's actually a JavaScript port of OpenGL, a long-established set of APIs that game developers use. Its primary target audience is existing games developers, who've been using OpenGL for ages, so they can write games for the web platform.
Nevertheless, there are resources to help you learn WebGL – and it's not just for games; we've seen fancy graphics, visualisatons and music videos made with it. Ones I can personally recommend are:
  • Introduction to WebGL and a look at the libraries available, by Luz Caballero.
  • Raw WebGL 101 – for those who think using a library is an admission of failure.
  • Learning WebGL – a very good tutorial site.
  • WebGL 101 – an instructional video by Erik Möller (2.5 hours).
  • See Emberwind, a game ported to webGL by Erik Möller. You can fork it on Github, or just see the code.

WebGL is present in all desktop browsers (released or dev channel) except for IE10 (Microsoft has said it won't support it). On mobile, it's released in Opera Mobile 12 final on Android, Blackberry Playbook 2.0, Nokia N900, Sony Ericsson Xperia Android phones and in development builds of Firefox Mobile.





Emberwind ported to WebGL by Erik Möller
Emberwind ported to WebGL by Erik Möller

SVG

Scalable Vector Graphics have been around for ages in Opera, Firefox, Safari and Chrome, but it wasn't until Internet Explorer began supporting it in IE9 that it became ready for primetime use, by which point it's been somewhat overshadowed by HTML5 <canvas>, although they are different tools for different jobs.
Canvas 2D is great for quickly painting graphics to a screen. But all you can do is paint; there is no memory of what is where, or what is 'on top' of what else; if you need that kind of book-keeping, you have to do it all yourself in JavaScript. Because it doesn't keep a DOM in memory, it's fast, so is great for things such as first-person shooters.
Conversely, SVG is great when you do need to keep a DOM. Objects can be moved around and animated independently with JavaScript. Try Daniel Davis' retro SVG game Inbox Attackand view source to see how animation is done.
Because shapes and paths are described with markup, they can be styled with CSS. Unlike<canvas>, text in SVG remains text and is therefore indexable, mash-upabble and accessible; in canvas, text just turns into pixels, like a Photoshop image of text.
But the real killer feature of SVG is that it's vector based – so your illustrations, graphs, UI icons and so on, will be just as clear and sharp on a 50 inch widescreen web-enabled TV as they will on a phone screen or desktop. In these web-anywhere days, that's important. SVG images can even include Media Queries so can be responsive, dropping nuances of shading or detail when you get down to small sizes, for example.
As mentioned above, there is wide support for SVG on the latest desktop browsers. Mobile support is also generally good, with the exception of the stock browser for Android before version 3.0.
Daniel Davis has a list of of SVG tutorial resources. I also recommend a free ebook: Learn SVG. See SVG or Canvas? Choosing between the two for more on the difference.





Inbox Attack - a retro SVG game by Daniel Davis
Inbox Attack – a retro SVG game by Daniel Davis

getUserMedia

Unlike many of the APIs that are erroneously called "HTML5", there's an excuse with getUserMedia – it started life as the HTML5 <device> element before becoming renamed and then hived off to the W3C's WebRTC suite of specifications.
gUM (as we shall now call it) allows access to a user's camera and microphone. I mentioned that it's part of the webRTC suite of specifications, which will enable peer-to-peer in-browser video conferencing. As gUM has other uses, too, it's separated out.
Camera access is implemented in Opera 12 final on Android, in Opera Desktop Labs and in Google Chrome Canary builds. Neither Opera nor Chrome yet implements microphone access.
The specification is still being worked on, so Opera and Webkit have different syntaxes, but a small JavaScript snippet called The gUM Shield can normalise those – more information in an article I wrote for HTML5 Doctor: It's Curtains for Marital Strife Thanks to getUserMedia.
Once video is streaming from the device, it can be made the source of a <video> element, which can be positioned off-screen if necessary, and then copied into <canvas> and manipulated as required. Paul Neave's HTML5 webcam toy copies the streaming data into WebGL in order to manipulate it (I interviewed him about this in issue 226 of .net magazine).
gUM goes a long way to giving web apps the same functionality as native apps. Trying Neave's gUM and WebGL demo on Opera Mobile 12 feels as responsive and snappy as platform-specific apps. As the functionality becomes widespread in production browsers, I predict lots of web-based QR code-readers and augmented reality apps.





Paul Neave's HTML5 Webcam Toy made with getUserMedia
Paul Neave's HTML5 Webcam Toy made with getUserMedia

File APIs

W3C File APIs allow JavaScript access to files on the local system. The most commonly-implemented API is FileReader, which is available in Opera, Firefox, Chrome and IE10 platform preview (but not Safari).
This spec "provides an API for representing file objects in web applications, as well as programmatically selecting them and accessing their data". For example, you can upload files into the browser and find out information such as name, size and type without having to go to the server. You can also open the file and manipulate its contents. This can enhance interactivity of browser-based applications to make them more like desktop applications.
One common use is to make a traditional image upload dialogue more Web 2.0-tastic by allowing dragging and dropping into the browser rather than navigating through the file system.
You start off with a normal <input type="file">, then progressively enhance it. Feature detect for HTML5 Drag and Drop support and, if present, replace the <input> with a <div>that will be a drag target for your image. When the image is dragged into the drag target, use the File Reader API to show a thumbnail of the image. See Remy Sharp's demo.
There are also specs for writing files and manipulating file systems, but these aren't sufficiently cross-browser to be currently usable.

Feature-detecting, progressive enhancement and upgrade messages

Of course, we should always try to progressively enhance basic, semantic HTML so that, if fancy APIs and the like are unavailable, the site still works. But sometimes, that's not possible. For example, with Paul Neave's HTML5 webcam toy, if gUM and WebGL aren't present, the website can't really take remedial action – the whole point of the site is lost.
In this case, there are typically two conventions: either show a message that says "Your browser is rubbish. Goodbye", or say "You need to use Chrome 6/ Firefox 4/ Opera 10 [insert your favourite browser that supports the technologies you're using]".
The first is unhelpful and just rude; it admonishes without suggesting a remedy. The second is a transient snapshot; in six months time, every other browser might support the tech you're using, yet your message is long out-of-date. Nothing suggests an abandoned site like telling the user to come back with Firefox 4 when they're visiting with Firefox 7.
If you really, really can't use progressive enhancement, then use the new HTML5 Please API. Created by Jon Neal, Divya Manian, and others, it interrogates caniuse.com and returns a list of the latest browsers that support the features you need:
If you've created a demo or site that requires Canvas or WebSQL DB, you've been in the awkward situation of telling some of your visitors that their browser isn't good enough. But you can't just recommend they get a browser with those features; for example, "Get a WebRTC capable browser" is pretty much useless to everyone.
The HTML5 Please API translates developer language (features) to user language (browsers). Call the API and you get back some HTML to show the user or a JSON object of the relevant data (with browser logos and all), so you can customise what you show to users.
What's particularly pleasant about this approach is that, if the API determines that all the features are supported by a newer version of the viewer's current browser, it suggests upgrading that rather than asking the user to change browser just to view your page.






That's all, folks

As you've seen there are loads of exciting technologies coming just around the corner. By the time you've come to grips with the ones we've discussed above, it'll be time to worry about a whole load more. Have fun; remember to test in as many browsers as possible.

20 Cheat Sheets for Web Development you must have



Every single time when you get stuck on some problem on web development, you may go to Google or break out the library of programming books. However, I am going to present you a lists of useful cheat sheets for your easy reference while doing your web development. Just bookmark this page, hence you can easily access to all of the cheat sheets if you find it helpful.

1) PHP

PHP Cheat Sheet

2) MYSQL

MYSQL Cheat Sheet

3) JavaScript

JavaScript Cheat Sheet

4) CSS

CSS Cheat Sheet

5) Regular Expression

Regular Expression

6) Apache’s mod_rewrite

Apache's mod_rewrite

7) HTML

HTML Cheat Sheet

8) HTML Character Entities

HTML Character Entities Cheat Sheet

9) RGB Hex Color Codes

RGB Hex Color Codes Cheat Sheet

10) jQuery

jQuery Cheat Sheet

11) SEO

SEO Cheat Sheet

12) HTML5

HTML5 Cheat Sheet

13) Google Analytical

 Google Analytics Cheat Sheet

14) WordPress

WordPress Cheat Sheet

15) Subversion

Subversion Cheat Sheet

16) Eclipse

Eclipse Cheat Sheet

17) Google Search Engine

Google Search Engine Cheat Sheet

18) Twitter

Twitter Cheat Sheet

19) CakePHP

CakePHP Cheat Sheet

20 CodeIgniter

CodeIgniter Cheat Sheet