浅析工厂方法(factory method)

来源:互联网 发布:seo网站建站 编辑:程序博客网 时间:2024/05/20 02:22

学习设计模式已经快两个月了,说真的由于自己的实际经验不够,看起来还是有点吃力,今天结合自己的感受谈一下学习工厂方法的看法,首先在这里我只是写个自己看了,并不是希望得到别人的认可了,因为我现在的水平真的还很菜了!呵呵,不乱吹了,我随时会修改了,因为理解随着学习会更加深刻了.

GOF:是一种对象创建型模式,它把类的实例的创建延迟到子类中完成,父工厂类只定义创建对象的公共接口,而子工厂类则负责生成具体的类的实例。

工厂方法是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化.

工厂方法的一个典型例子:迭代器

迭代器模式提供了一种顺序访问集合中的元素的方法,然而通常用iterator()方法本身却是一个工厂方法模式的很好的例子,该方法使得调用方无需了解所要实例化的类,JDK引入了collection()接口,该接口包含了一个iterator()方法,所有的集合都要实现该接口,通过集合创建了一个对象,该对象返回集合中的各个元素的序列,例如,下面的代码创建了一个列表对象,并将他的元素打印出来.

public class ShowIterator{

           public static void mian(String args[]){

                 List list=Array.asList(new String[]{"foundation","rocket","sparkler"});

                 Iterator i=list.iterator();

                 while(i.hasNext()){

                            System.out.prinltn(i.next());

}

}

}

在工厂方法模式中,工厂方法的用户不必知道该实例化那个类,上面的iterator()方法很好的示范了这个特性.

呵呵上面那个例子可能太抽象了,下面结合书上的祥细的例子讲解了.

日志记录是软件开发中常用的功能之一,我们有时候需要日志向打到控制台,有时侯打到文件了,因此将实际的日志的记录功能保留在公共的程序内部是一个很好的想法了,这样客户机对象就无需重复这些详细信息.定义一个JAVA接口Logger,声明该接口有客户机对象用于记录消息,一般来说.进来的消息可以按不同的格式记录到不同的输出的介质上,因为Logger接口的不同具体实现者类可以在实施中处理这些差异,定义这两个实施者.Logger接口代码如下:

public interface Logger {
      public void log(String msg);
}

Logger实施者代码如下:

public class ConsoleLogger implements Logger {

 @Override
 public void log(String msg) {
  // TODO Auto-generated method stub

  System.out.println(msg);

 }
}
public class FileLogger implements Logger {

 @Override
 public void log(String msg) {
  // TODO Auto-generated method stub
  File futil=new FileUtil();
  futil.writeToFile("log.txt",msg,true,true);

 }

}
应用工厂方法模式,选择相应的Logger实施者所需的实施可以封装在单独类LoggerFactory中的单独方法getLogger工厂方法的内部.

作为工厂方法实施的一部分,工厂方法法getLogger会检查logger.properties属性文件以查看是否启用文件记录的功能.并决定要选定那个Logger实施者将作为Logger类型的对象返回.

使用工厂方法,客户机对象无需处理选择和例示相应的Logger实施者出现的复杂状况.也无需了解Logger接口的不同实施者的存在性及相关功能.LoggerFactory代码如下:

package org;

import java.io.IOException;
import java.util.Properties;

public class LoggerFactory {
         public boolean isFileLoggingEnabled(){
          Properties p=new Properties();
          try{
           p.load(ClassLoader.getSystemResourceAsStream("Logger.properties"));
           String fileLoggingValue=p.getProperty("FileLogging");
           if(fileLoggingValue.equalsIgnoreCase("ON")==true)
            return true;
           else
            return false;
          }catch (IOException e){
           return false;
          }
         }
 //Factory Method
         public Logger getLogger(){
          if(isFileLoggingEnabled()){
           return new FileLogger();
          }else {
           return new ConsoleLogger();
          }
         }
}
客户机LoggerTest代码如下:

public class LoggerTest {
        public static void main(String args[]){
         LoggerFactory factory=new LoggerFactory();
         Logger logger=factory.getLogger();
         logger.log("A Message to Log");
        }

}
 在本应用中,我们使用工厂方法的默认实施将创建者类LoggerFactory设计为具体的类。我的感受是在工厂类中完成客户机的类选择功能,这样让客户机不用知道自己去选择那个类,我觉的这也是接口的一个用法,其实我觉的工厂方法跟接口怎么这么功能上象了,可能是我理解还不够深刻了,加油了,这几天看设计模式,真的好东西,偶觉的简直是艺术啊,程序设计的艺术啊!太强了!加油了,呵呵!打字真的太慢了,花了我将近一个小时啊!加油了!

我想说的是,我们不仅应该关心一个具体的模式有什么作用,如何去实现这个模式,更应该透过现象看本质,不但知其然,还要知其所以然.要通过对模式的学习加深对面向对象思想的理解,让自己的认识得到升华.Factory Method模式看似简单,实则深刻.抽象,封装,继承,委托,多态,针对接口编程等面向对象中的概念都在这里得到了一一的体现.只有抓住了它的本质,我们才能够不拘于形式的灵活运用,而不是为了使用模式而使用模式.

原创粉丝点击