PUT or POST: The REST API

The crux of the issue comes down to a concept known as idempotency. An operation is idempotent if a sequence of two or more of the same operation results in the same resource state as would a single instance of that operation. According to the HTTP 1.1 specification, GET, HEAD, PUT and DELETE are idempotent,…

mvc vs mvp

n MVC, the model stores the data, the view is a representation of that data, and the controller allows the user to change the data. When the data is changed, all views are notified of the change and they can update themselves as necessary (think EventDispatcher). MVP is a derivative of MVC, mostly aimed at…

Java 中的Iterator模式

下午要quiz Iterator,赶紧复习了下~ 通过collection 类 的 Iterator接口,可以隐藏内部实现, 貌似1.5之后都有实现了Iterable接口,可以直接foreach了,不过了解一下这种设计模式还是很有意义的。 public interface Iterator {  boolean hasNext();  Object next();  void remove(); }  client一般只操作next和hasNext方法,不关心representation,达到分离的目的! 具体实现是:拿AbstracyList为例,里面先提供一个内部类: private class Itr implements Iterator { … }   而iterator()方法的定义是:  public Iterator iterator() {  return new Itr(); }  因此client不知道它通过Iterator it = a.iterator();所获得的Iterator的真正类型。 现在我们关心的是这个申明为private的Itr类是如何实现遍历AbstractList的:  private class Itr implements Iterator {  int cursor = 0;  int lastRet = -1;  int expectedModCount = modCount; }    Itr类依靠3个int变量(还有一个隐含的AbstractList的引用)来实现遍历,cursor是下一次next()调用时元素的位置,第一次调用next()将返回索引为0的元素。lastRet记录上一次游标所在位置,因此它总是比cursor少1。    变量cursor和集合的元素个数决定hasNext():  public boolean hasNext() {  return…

Decorator模式(装饰者)

定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。   设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。   实际上Java 的I/O API就是使用Decorator实现的。    在此 以一家人作画为例写了5个java类来描述说明Decorator设计模式的实现方式;   这个例子举的不太好,但足以说明问题。下面是具体的代码。    1、 Work.java     接口 2、 Son.java      被装饰者-负责画画 3、 Mother.java   装饰者-负责上颜色 4、 Father.java   装饰者-负责装画框 5、 DecoratorTest.java 带有main方法的测试类,         模拟3种调用情况:A,只画画;                          B,画画,上色;                          C, 画画,上色,装框   ===============   1、 Work.javapackage decorator; public interface Work {  public void paint();}===============   1   end   ===============   2、 Son.javapackage decorator; public class Son implements Work {  public void paint()…

prototype模式

要理解原型原型模式必须先理解Java里的浅复制和深复制。有的地方,复制也叫做克隆。Java提供这两种克隆方式。     浅克隆:被克隆对象的所有变量都含有与原来的对象相同的值,而它所有的对其他对象的引用都仍然指向原来的对象。换一种说法就是浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象。     深克隆:被克隆对象的所有变量都含有与原来的对象相同的值,但它所有的对其他对象的引用不再是原有的,而这是指向被复制过的新对象。换言之,深复制把要复制的对象的所有引用的对象都复制了一遍,这种叫做间接复制。深复制的源代码如下:    Java代码 public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException            {                //write to stream                ByteArrayOutputStream bo = new ByteArrayOutputStream();                ObjectOutputStream oo = new ObjectOutputStream(bo);                oo.writeObject(this);        //read from stream      ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());                ObjectInputStream oi = new ObjectInputStream(bi);                  return (oi.readObject());            }   public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException { //write to stream ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); //read from…

Builder模式

定义一个文件生成器。文件的类:MyFile 分为三个部分,也就是说有三个属性:FileHead,FileContent,FileEnd。FileHead定义如下: package create.builder1;public class FileHead { private String value;  public String getValue() {  return value; }  public void setValue(String value) {  this.value = value; }} FileContent定义如下: package create.builder1;public class FileContent { private String value;  public String getValue() {  return value; }  public void setValue(String value) {  this.value = value; }} FileEnd 定义如下: package create.builder1;public class FileEnd { private String value;  public String getValue() {  return value; }…

Command模式示例代码

Command模式示例代码 一个简单的例子,它通过Command模式实现回调机制。以Fan(风扇)和Light(灯)为例。我们的目标是设计一个Switch,它可以对任一个对象进行 ‘开’ 和 ‘关’ 的操作。Fan和Light具有不同的接口,这意味着Switch必须独立于接收者接口,或者说,它不清楚接收者的接口。为了解决这一问题,每个Switch都需要合适的command作为参数。很明显,连接到Light的Switch和连接到Fan的Switch具有不同的command。因此,Command类必须是抽象的,或者是个接口。Switch的构造函数被调用时,它以一组合适的command作为参数。command作为Switch的私有变量保存下来。调用flipUp()和flipDown()操作时,它们只是简单地让合适的command进行execute()操作。Switch对调用execute()后将发生些什么一无所知。TestCommand.javaclass Fan {        public void startRotate() {                System.out.println(‘Fan is rotating’);        }        public void stopRotate() {                System.out.println(‘Fan is not rotating’);        }}class Light {        public void turnOn( ) {                System.out.println(‘Light is on ‘);        }        public void turnOff( ) {                System.out.println(‘Light is off’);        }}class Switch {        private Command UpCommand, DownCommand;        public Switch( Command…

bridge 模式的一个例子

本文介绍设计模式中的桥接(Bridge)模式的概念,用法,以及实际应用中怎么样使用桥接模式进行开发。 Bridge模式的概念 Bridge模式是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。 Bridge模式的应用场景 面向对象的程序设计(OOP)里有类继承(子类继承父类)的概念,如果一个类或接口有多个具体实现子类,如果这些子类具有以下特性:– 存在相对并列的子类属性。– 存在概念上的交叉。– 可变性。我们就可以用Bridge模式来对其进行抽象与具体,对相关类进行重构。 为了容易理解,我们举例说明一下,比如汽车类(Car),假设有2个子类,卡车类(Truck)与公交车类(Bus),它们有[设置引擎]这个动作行为,通过不同引擎规格的设置,可以将它们设置为比如为1500cc(Car1500),和2000cc(Car2000)的车。这样,不管是1500cc的卡车还是2000cc的卡车,抑或是1500cc的公交车还是2000cc的公交车,它们都可以是汽车类的子类,而且:– 存在相对并列的子类属性。汽车的种类,与汽车引擎规格是汽车的2个并列的属性,没有概念上的重复。– 存在概念上的交叉。不管是卡车还是公交车,都有1500cc与2000cc引擎规格的车。– 可变性。除了卡车,公交车之外,可能还有救火车;除了有1500cc与2000cc引擎规格的车之外,还可能有2500cc的车等等。 这样一来,我们怎么来设计汽车类呢?1,方法一:通过继承设计所有可能存在的子类。可能我们会想到下面的这种继承关系:汽车总类:Car汽车子类 – 按种类分类:Bus,Truck汽车子类 – 按引擎分类:Bus1500,Bus2000,Truck1500,Truck2000这样设置引擎这个动作就由各个子类加以实现。 但如果以后需要增加一种救火车(FireCar),以及增加一个引擎规格2500cc,需要实现的子类将会有:Bus1500,Bus2000,Bus2500,Truck1500,Truck2000,Truck2500,FireCar1500,FireCar2000,FireCar2500多达9个。也就是说,这种设计方法,子类数目将随几何级数增长。而且,Bus1500,Truck1500的引擎规格相同,它们的引擎设置动作应该是一样的,但现在把它们分成不同的子类,难以避免执行重复的动作行为。 2,方法二:分别为Bus以及Truck实现设置不同引擎的方法汽车总类:Car汽车子类:Bus,Truck 然后在Bus类里分别提供1500cc以及2000cc引擎的设置方法:Bus extends Car {    public setEngine1500cc();    public setEngine2000cc();} 在Truck类里也分别提供1500cc以及2000cc引擎的设置方法:Truck extends Car {    public setEngine1500cc();    public setEngine2000cc();} 这种情况,子类的数量是被控制了。但一方面,如果每增加一种引擎规格,需要修改所有的汽车子类;另一方面,即使引擎的设置行为一样,但是不同的汽车子类却需要提供完全一样的方法。 在实际的应用开发中,以上2种方法都会造成迁一发而动全身,而且会存在大量的重复代码。 Bridge模式可以很好的解决这类问题。我们先看看Bridge模式的类图描述:[图:出自wikipedia.org] Client    Bridge模式的使用者Abstraction    抽象类接口(接口或抽象类)    维护对行为实现(Implementor)的引用Refined Abstraction    Abstraction子类Implementor    行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作)ConcreteImplementor    Implementor子类 Bridge模式的应用范例 我们来看看怎么应用Bridge模式来设计汽车类。 抽象 – Abstraction类:汽车类及其子类:Car:汽车总类Truck:汽车子类 – 卡车类。Bus:汽车子类 – 公交车类。 行为实现 – Implementor:汽车引擎设置的行为类及子类SetCarEngine:汽车引擎的设置接口SetCarEngine1500cc:设置1500cc引擎SetCarEngine2000cc:设置2000cc引擎 Client类:使用Bridge模式Client:测试 代码: view plaincopy to clipboardprint?…

mediator模式

  中介者模式和观察者模式的区别是,前者应用于多对多杂乱交互行为的统筹处理,后者应用于一(多)对多关系的灵活定制。对于本例来说,集中处理后还需要分散处理,那么后半阶段的处理过程可以应用观察者模式。对于前一节的例子来说,如果有多个主体角色和多个观察者进行多对多通讯的话,也可以应用中介者模式来统筹这个多对多的过程(大家可以自己尝试修改前一节的实例来应用中介者模式)。  中介者模式和门面模式的区别是,前者的各同事类需要依靠中介者进行双向通讯,应用于子系统之间,而后者的子系统往往不会通过门面去和调用方进行通讯,趋向于单向通讯,应用于子系列和更高层次的系统。本例中就有门面模式和中介者模式的影子。  中介者模式往往可以在构架的层次进行应用,有的时候和观察者模式以及门面模式一起使用,有的时候又会向观察者模式和门面模式退化。其实在应用模式的过程中不必过多考虑模式的准确定位,如果我们确实从中得以,那么这个名字就不重要了。

一个composite(树形模式比较适合)的好例子

将对象组合成树形结构以表示“整体—部分”的层次结构。Composite模式使单个对象和组合对象的使用具有一致性。   下面给出这个模式的结构图:   如果把Composite模式看成是树形结构的话,那么它主要角色有:   1)树干角色(Component):该角色是一个抽象类,它定义了一些操作增删树叶(Leaf)的操作。   2)树枝角色(Composite):树枝上有很多树干,树枝也是树干的一种。   3)树叶角色(Leaf):树干上的树叶,也就是Component中的具体操作对象。   说到Composite模式,让我想到以前项目中遇到的一个问题,做一个影视节目列表的树形结构,要求支持二级分类,由于当时还没接触过设计模式,这个东西让我搞了好久,才弄好。   现在使用Composite模式来解决这个问题,简直太简单了,别说是二级了,N级都没问题。下面我就用Composite来实现它,代码如下: import java.util.ArrayList;  abstract class MovieClass{//Componentpublic String name;public ArrayList<MovieClass> list;public abstract void add(MovieClass component);public abstract void remove(MovieClass component);public abstract void display();}class Program extends MovieClass{//Leafpublic Program(String name){ this.name=name;}  public void add(MovieClass component){  System.out.println(“you can’t add component to a proagram object”);}  public void display() { System.out.println(“———-“+name);}  public void remove(MovieClass component) { System.out.println(“you can’t remove component to a proagram…

一个flyweight的好例子!

使用共享对象可有效地支持大量的细粒度的对象。 图1展示了Flyweight 设计模式的一个类图。 图1. Flyweight 类图 Flyweights可通过flyweight factory的例子来说明,这个flyweight factory创建了一定数量的flyweights并将他们定期的发放给客户端,一次发放一个。 这些flyweights 可根据某些标准显示。例如:你有一个知道如何划出直线的直线对象池。这时, flyweight factory就能为每一个直线颜色创建一个直线对象,如一个对象用于白线,另一个对象用于蓝线。这些线,也就是flyweights,只要你画白线或者画蓝线,他们就会重新使用。如果你要画1000条白线和6000条蓝线,实际上只显示两条线,而不是7000条线。 图2的流程图描述了客户端和flyweight factory的交互过程。 图2. Flyweight流程图 客户端程序并不直接显示flyweights;相反的它们只是从flyweight factory中读取flyweight。flyweight factory首先检查自己是否有符合特别标准(如,蓝线或者白线)的 flyweight ;如果有,就返回对该flyweight的访问。如果它不能找到符合标准的flyweight ,就会自己产生一个,加到共享池内,并将它返回给客户端程序。i 你可能不知道如何重新使用flyweights。例如:直线flyweight 如何才能画出所有这些位置和长度都不同的指定颜色的直线呢?要完成这个任务,你可将flyweight状态劈为两个状态:intrinsic 状态(如直线颜色)和extrinsic 状态(直线位置和长度)。这样flyweight 保存了内在状态,而外部状态必须在运行过程中传递给flyweight。 通过具体化外部状态,你可以轻松的重新使用适合于各种不同外部状态的flyweight。 例子演示 接下来本文将带你实现一个直线flyweight ,它与本文开头讨论过的直线flyweight 类似。我们将用三个方法来完成这件工作。第一,我不借助直线对象,只是重复地在图形语境内绘出10,000直线。第二,我实现一个不能共享的简单的Line 类。第三,我就这个简单的类变成flyweight。图5显示了重复描绘直线的应用程序。 图5 使用Swing描绘直线 不使用直线对象的制图 Example 3 列表显示了图5的应用程序。 Example 3. Drawing lines without line objects import java.awt.*; import java.awt.event.*; import javax.swing.*; …

2010-4-27

 看了看singleton,貌似不是非常有用的模式了!用private的constructor,然后static的Factory方法提供单例!Factory中的instance当然也是static的。 最重要的作用应该就是节省资源吧!还以为Calendar类也是singleton,因为它也是getInstance()方法来获得,google了一下,不是的,momo!通过getInstance是因为它的constructor是protected。 看来什么都不能想当然呀!它是每次都获得一个新实例!感觉这个应该可以作为单例吧。。。再看看~ 明天考试!bless!!!