Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1504202
  • 博文数量: 164
  • 博客积分: 2993
  • 博客等级: 少校
  • 技术积分: 1718
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-24 11:42
文章分类

全部博文(164)

文章存档

2014年(1)

2013年(36)

2012年(90)

2011年(37)

分类: 系统运维

2012-05-07 15:35:23

      今天上午做了设计模式的培训。以前自以为看懂了一些模式的东西,现在觉得还是有很多的东西没有理解到。每次说起一种模式有多少种分类时,常常会被人笑话又问茴香豆的茴字有几种写法。但是,我觉得不是的,只有当你能够深刻理解你为什么要那样做,那样做有什么好处的时候,你才算真正的明白了设计模式。

       今天开会的时候,还说到一个话题,就是设计模式有几个基本的原则,这些原则是设计模式产生的根本原因。我觉得说的对,稍后我会把那些内容补上。

      这次我们学习了好几个模式,我个人认为有几个模式我并没有参透,所以暂时写写我理解了的一两个吧!首先是简单工厂模式。 这个模式说起来很简单,使用一个类,类里包含一个方法,该方法根据传递进来的参数决定返回的类实例。 以前,我以为随便想要什么类,传个参数进去,然后把类实例返回就好了。现在想想很傻。因为我忽略了返回值类型啊!所以简单工厂中,方法的返回类型限制,要求创建出来的类必须实现了共同的接口,或继承了共同的父类。

使用简单工厂的原因:

       下面举个实在的例子: 假设你有一个院子,院子里中了很多水果,苹果,草莓和葡萄。有一个园丁在管理他们,如果需要的时候就去园丁那里获取。 

       如果按照普通的定义,我们会定义苹果,草莓和葡萄,园丁几个类,需要哪个用哪个。

       这样做有什么问题呢?如果有一天我希望原来的苹果全部换成草莓,怎么办?一个个的替换掉吗?显然不好啊!!如果我们使用简单工厂模式,直接改变方法返回的值就ok了!

       所以,原因一:替换简单,程序的灵活性更强。

        除此之外,如果我们新增了一个水果类,比如香蕉,我们不必在别的地方处理,只需在工厂中增加一个判断就可以了。

       所以,原因二:扩展方便,快捷。

如何实现简单工厂:

1.共有的接口

 public interface Fruit {
   void grow();
   void harvest();
   void plant();
}

2.各个具体实现类:

//苹果
public class Apple implements Fruit{
  private int treeAge;
  public void setTreeAge(int treeAge) {
    this.treeAge = treeAge;
  }

  public int getTreeAge() {
    return treeAge;
  }

  /**
   * grow
   */
  public void grow() {
    System.out.println("Apple is growing...");
  }


  /**
   * harvest
   */
  public void harvest() {
    System.out.println("apple had harvested");
  }

  /**
   * plant
   */
  public void plant() {
    System.out.println("apple had planted");
  }
}

//葡萄

public class Grape implements Fruit{
  private boolean seedless;

  public boolean getSeedless()
  {
    return seedless;
  }

  public void setSeedless()
  {
    this.seedless = seedless;
  }

  public Grape() {
  }

  /**
   * grow
   */
  public void grow() {
    System.out.println("Grape is growing");
  }

  /**
   * harvest
   */
  public void harvest() {
    System.out.println("grape is havest");
  }

  /**
   * plant
   */
  public void plant() {
    System.out.println("grape is planted");
  }

}

3.园丁工厂:

public class FruitGardener {
  public static Fruit factory(String which) throws Exception
  {
    if(which.equals("apple"))
    {
      return new Apple();
    }else if(which.equalsIgnoreCase("Grape"))
    {
      return new Grape();
    }
    else
    {
        throw new Exception("no this fruit!");
    }
  }

}

 



简单工厂模式的扩展:

     前面的设计虽然扩展起来是很容易的,但是还是有些问题,就是每次添加类的时候需要到工厂中增加一个处理。如果你不希望那样,怎么办呢?下面的代码就解决了这个问题了。

public class FruitGardener {
  public static Fruit factory(String which) throws Exception
  {

         return (Fruit)Class.forName(which).newInstance();
    }

}

但是这个方法还存在以下的缺点:

      1.有时候仅仅newInstance()不一定足够,比如创建苹果的例子,还要带一个颜色参数,
  当然还有更复杂的例子,如创建一个jndi对象,如从池里取对象等等。


       2.有时候不是简单的传入一个className,还需要对传入的参数作分析以创建不通的对象, 如jdbc根据不同的连接串创建不同的Connection。再比如,如果使用苹果的地方都需要换成葡萄只需要将switch语句对应苹果的一句换成葡萄类的实例就好。但是用上面的方法就不可取了。

 

简单工厂的缺点

     上面我们谈了简单工厂的优点和扩展。下面我们来看看简单工厂的缺点。有一个被认为最不好的缺点,就是不符合OCP原则。也就是说,当你增加一个新类时,你必须修改工厂方法,添加一段处理代码。这不符合,已有代码尽可能不改变的原则。于是工厂方法模式应运而生了。

阅读(619) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~