设计模式-工厂模式-简单工厂

来源:互联网 发布:js offset client 编辑:程序博客网 时间:2024/04/30 09:09

  最近在学习java 的设计模式,在网上看到了很多资料。全部总结在这里,希望大家互相学习。

Java 有 23 种设计模式,可分为三类:

1.创建模式

2.行为模式

3.结构模式 

在本文章中首先对创建模式进行介绍: 

 

n
创建模式分为类的创建模式对象的创建模式两种。
#对象的创建模式:是把对象的创建过程动态的委派给另一个对象,从而动态地决定客户端将得到哪些具体类的实例,以及这些类的实例是如何被创建和组合在一起的.
#类的创建模式:类的创建模式使用继承关系,把类的创建延迟到子类,从而封装了客户端将得到哪些具体类的信息,并且隐藏了这些类的实例是如何被创建和放在一起的。 创建模式(Creational Pattern)是对类的实例化过程的抽象化。一些系统在创建对象时,需要动态地决定怎样创建对象,创建哪些对象,以及如何组合和表示这些对象。创建模式描述了怎样构造和封装这些动态的决定。
l
l
创建模式按常用功能可以分为四种:
1.简单工厂模式  (Simple Factory)
2.工厂方法模式  (Factory Method)
3.抽象工厂模式  (Abstract Factory)
4.单例模式模式  (Singleton)
第一:介绍简单工厂模式
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
#怎样实现简单工厂:
   简单工厂使用了java的 接口技术,那么我们怎样实现简单工厂呢:
    1,定义接口(Fruit)
    2,创建 实现接口 的类 (Grape,Strawberry,Apple)
    3,创建 工厂类(FruitGardener)
    4,在客户端 创建工厂对象,进而产生实例对象。
引入简单工厂模式
下面让我们来分析几个需求,然后我们使用简单工厂对其进行设计,看看能够给我的带来什么样的好处。
需求1:有一个农场公司,专门向市场销售各类水果,在这个系统里需要描述下列的水果:
l葡萄 Grape
l草莓 Strawberry
l苹果 Apple
 首先我们认知到农场里可能还有不是水果类的植物,那么我们为了可以把它们和水果区分开,我们就需要为水果提供一个共通的定义凡是具有这种定义的我们就似其为水果。
定义一个接口 Fruit
public interface Fruit
 }
对于水果来说其具有:种植,生长,收获的共通行为。
public interface Fruit{
   void grow();//生长
   void harvest();//收获
   void plant();//种植
}
 
整体的类设计结构如下图:
 
    让我们根据分析后的UML来分别编写我们的具体实现:
Apple 是水果的一种,因此它实现了水果接口所声明的所有方法。另外,由于苹果是多年生植物,因此多出一个treeAge属性,描述苹果树的年龄。
public class Apple implements Fruit{
public void grow(){
    System.out.println("Apple is growing...");
}
public void harvest(){
    System.out.println("Apple has been harvested.");
}
 public void plant(){
    System.out.println("Apple has been planted.");
}
public int getTreeAge()
{
     return treeAge;
}
public void setTreeAge(int treeAge)
{
    this.treeAge = treeAge;
 }
private int treeAge;
}
 
同样,Grape类是水果类的一种,也实现了Fruit接口。但由于葡萄分有籽和无籽两种,因此,比通常的水果多出一个seedless属性。
public class Grape implements Fruit{
public void grow(){
 System.out.println("Grape is growing...");
}
public void harvest(){
                      System.out.println("Grape has been harvested.");
}
public void plant(){
     System.out.println("Grape has been planted.");
}
public boolean getSeedless(){
 return seedless;
}
public void setSeedless(boolean seedless){
 this.seedless = seedless;
}
private boolean seedless;
}
 
Strawberry 类实现了Fruit接口,因此,也是水果类的子类型。
public class Strawberry implements Fruit{
    public void grow(){
    System.out.println("Strawberry is growing...");
    }
    public void harvest(){
    System.out.println("Strawberry has been harvested.");
    }
    public void plant(){
      System.out.println("Strawberry has been planted.");
    }
}
 
让我们再次的来分析一下我们的系统,水果是不可能自己种自己的,所以在我们的系统中还缺一个园丁,那么现在就让我们考虑一下关于园丁类的设计把。
首先我们知道我们需要的是一个会种水果的园丁FruitGardener,其次我们要告诉园丁我们需要他种植什么样的水果,也就是说园丁要被一种行为去驱动。
定义FruitGardener类
public class FruitGardener{}
前面分析过园丁是按照行为驱动的,而取得的结果是种植出我们想要的水果。所以添加方法
createFruit(String which)返回值是Fruit
public class FruitGardener{
    public static Fruit createFruit(String which) {}
}
而前面我们知道我们需要葡萄(Grape)、草莓(Strawberry)、苹果(Apple)那么我们就根据我们的需求来添加方法的行为。
public static Fruit createFruit(String which){
 if (which.equalsIgnoreCase("apple")){
      return new Apple();
 }
 else if (which.equalsIgnoreCase("strawberry")){
      return new Strawberry();
 }
 else if (which.equalsIgnoreCase("grape")){
            return new Grape();
        }
}
客户端应用:
public class FruitManerger
{
      public static void main(String[] args)
      {
             Fruit fruit =  FruitGardener.createFruit("apple");
             fruit.plant();
      }
 
}
现在在让我们来完善我们的设计,因为是由FruitGardener根据我们的行为指令来决定种植何种水果,那么也就是说如果我们的指令对FruitGardener来说是不可能完成的那么他也应该告诉我们他无法种植,所以我们要设计一个异常BadFruitException
public class BadFruitException extends Exception{
private static final long serialVersionUID = 4506528838794787503L;
public BadFruitException(String msg){
     super(msg);
}
}
然后我们更改createFruit
public static Fruit createFruit(String which) throws BadFruitException{
 if (which.equalsIgnoreCase("apple")){
      return new Apple();
 }
 else if (which.equalsIgnoreCase("strawberry")){
      return new Strawberry();
 }
 else if (which.equalsIgnoreCase("grape")){
            return new Grape();
 } else{
            throw new BadFruitException("Bad fruit request");
   }
}
 
回顾:我们的设计完成了,我们回头看看我们的代码,在想想关于简单工厂模式的定义
我们会发现createFruit就是一个简单工厂模式的应用。
我们可以通过下面的图形来表明一个简单工厂的一般性结构:
 
任何的事物都有其正反两面,那下面在让我们看看简单工厂的优点和缺点的对比。
l优点
 使用简单工厂使得客户端和业务层有效的被隔离开,由工厂来根据客户端的请求来创建适合的业务对象,让后在返回给客户端。客户端不知道业务对象是如何被创建的而业务层也不知道客户端的存在,也就是说对于客户端来说业务对象是透明的,而对于业务层客户端同样也是透明的,这样就实现的客户端和业务层的解耦合。
l缺点
 因为所有的业务对象的实例化逻辑都是由这个简单工厂实现,也就是说这个工厂类集中了所有的产品创建逻辑,形成了一个无所不知的全能类,也称之为 God Class,当业务对象层次很复杂时这个工厂存在大量的判断逻辑,对系统的扩展和文档性带来了负面的影响。
原创粉丝点击