Android开发中抽象工厂模式

来源:互联网 发布:linux 删除匹配文件名 编辑:程序博客网 时间:2024/06/06 09:39

模式解读

  abstract 是“抽象”,factory 是“工厂”,所以合起来abstract factory 就是“抽象工厂”的意思。Abstract Factory Pattern 中的抽象工厂则是把各种抽象零件合成抽象产品。换句话说,处理的重点是在接口(api)而不是零件的具体实现。只利用接口(API)就能把零件组合成产品。
  模板方法模式和生成模式的情形 是在子类进行具体的实现,而抽象工厂模式也同样是由子类来处理具体 的实现。在子类就会出现具体工厂利用具体零件组合而成的具体产品。

  程序示例

  本篇涉及的类较多,较之单例模式而言理解真来比较难。一步步来吧。
  本例将使用抽象工厂,制作输出一个HTML语言显示在Android 的文本上。由于涉及类比较多,先上UML图,再一一解释:

  抽象零件:Item 类

  caption字段 是此项目的“标题”。
  makeHtml 方法是抽象方法,须等待子类进行实现。一旦调用 此方法时,其返回值即为HTML字符串(子类要有这样的执行功能)。
  代码:

  public abstract class Item {

      protected String caption;
      
      public Item(String caption){
          this.caption=caption;
      }
    
      public abstract String makeHTML();

  }

抽象零件:Link 类

  Link 类是以抽象方式表示 HTML超链接的类。
  url 字段用来存储超链网站的URL。该抽象类实现Item 抽象类。
  代码 :

  /**
   * 以抽象方式 表示HTML超链接的类
   * @author Administrator
   *
   */
  public abstract class Link extends Item{

      protected String url;
      public Link(String caption,String url) {
          super(caption);
          // TODO Auto-generated constructor stub
          this.url=url;
      }

  }

  抽象零件:Tray类

  Tray 类是表示 收集一个以上的Link 或Tray 类。
  Link 和Tray 则利用add 方法把它们 找出来。add 方法对于“LINK”和“Tray” 这部分的表现方式则是将Link 和 Tray 的父类Item 设为参数。
  Tray 类继承 了Item 类的抽象方法makeHTML,但并未实现。所以Tray 类也是抽象类。
  代码 :

  /**
   * 表示收集一个以上的Link 或Tray的类
   * @author Administrator
   *
   */
  public abstract class Tray extends Item{

      protected Vector<Item> tray=new Vector<Item>();

      public Tray(String caption) {
          super(caption);
          // TODO Auto-generated constructor stub
      }
    
      public void add(Item item){
          tray.add(item);
      }

  }

  抽象产品:Page 类

  Page 类则是以抽象的方式表现整个HTML网页的类。如果说LINK和TRAY是抽象零件,那么Page 类就可以说是抽象的“产品”(负责最终输出HTML)。Title字段是网页的标题,author 是网页的作者。最后以OutPut 输出数据。
  代码 :

  /**
   * 以抽象的方式表现整个HTML网页的类
   * 
   * @author Administrator
   * 
   */
  public abstract class Page {

      protected String title;
      protected String author;
      protected Vector<Item> content=new Vector<Item>();

      public Page(String title, String author) {
          this.title = title;
          this.author = author;
      }
    
    
    
      public void add(Item item){
          content.add(item);
      }

    
      public String outPut(){
          StringBuffer sb=new StringBuffer();
          sb.append(title+".html\n");
          sb.append(makeHtml());
          return sb.toString();
        
      }
    
      public abstract String makeHtml();
  }

  抽象产品参与 者规定由抽象工厂参与者所产生的抽象零件和产品的接口(API)。扮演这个参与者的是LINK类、Tray 类和Page 类。

抽象工厂:Factory 类

  该类包含一个getFactory 方法,利用参数Class<?>得到一个类的对象实例。
  在抽象工厂制作零件或产品时,会用到createLink、createTray、createPage这几个方法。这些方法都是抽象方法,实际上的具体零件和产品制作过程则交给Factory 的子类来处理,方法是由这里来规定。
  代码 :

  /**
   * 抽象工厂,在抽象工厂通过各个零件制作成产品
   * 
   * @author Administrator
   * 
   */
  public abstract class Factory {

      public static Factory getFactory(Class<?> cls) {
          Factory factory = null;

          try {
              factory = (Factory) cls.newInstance();
          } catch (InstantiationException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IllegalAccessException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

          return factory;
      }

      public abstract Link createLink(String caption, String url);

      public abstract Tray createTray(String caption);

      public abstract Page createPage(String title, String author);

  }

  抽象工厂参与者则规定用来产生抽象产品参与者的对象实例的接口 (API),扮演这个角色的是Factory 类。

  具体工厂:ListFactory 类

  该类实现Factory 类的抽象方法createLink 、createTray、createPage。这里的实现工具调用 new 函数把ListLink 、ListTray 、ListPage 创建出来(可以利用之前写过的Prototype 进行clone) 。
  代码:

  /**
   * 具体工厂
   * 
   * @author Administrator
   * 
   */
  public class ListFactory extends Factory {

      @Override
      public Link createLink(String caption, String url) {
          // TODO Auto-generated method stub
          return new ListLink(caption, url);
      }

      @Override
      public Page createPage(String title, String author) {
          // TODO Auto-generated method stub
          return new ListPage(title, author);
      }

      @Override
      public Tray createTray(String caption) {
          // TODO Auto-generated method stub
          return new ListTray(caption);
      }

  }

  具体零件:ListLink 类

  该类为Link 的子类,负责实现Link 的makeHTML抽象方法。
  代码:

  public class ListLink extends Link {

      public ListLink(String caption, String url) {
          super(caption, url);
          // TODO Auto-generated constructor stub
      }

      @Override
      public String makeHTML() {
          // TODO Auto-generated method stub
          return " <li><a href=\"" + url + "\">" + caption + "</a></li>\n";
      }

  }

  具体零件:ListTray类

  该类为Tray 的子类,同上文一样负责实现抽象类Tray 的makeHtml方法。
  代码:

  public class ListTray extends Tray {

      public ListTray(String caption) {
          super(caption);
          // TODO Auto-generated constructor stub
      }

      @Override
      public String makeHTML() {
          // TODO Auto-generated method stub
          StringBuffer sb = new StringBuffer();

          sb.append("<li>\n");
          sb.append(caption + "\n");
          sb.append("<ul>\n");
          Iterator<Item> it = tray.iterator();
          while (it.hasNext()) {
              Item item=(Item)it.next();
              sb.append(item.makeHTML());    //调用 ListLink实现完成后的makeHtml
          }
          sb.append("</ul>\n");
          sb.append("</li>\n");
          return sb.toString();
      }

  }

抽象零件:ListPage类

  原理与上文相似。
  代码:

  public class ListPage extends Page {

      public ListPage(String title, String author) {
          super(title, author);
          // TODO Auto-generated constructor stub
      }

      @Override
      public String makeHtml() {
          // TODO Auto-generated method stub
          StringBuffer sb = new StringBuffer();
          sb.append("<html><head><title>" + title + "</title></head>\n");
          sb.append("<body>\n");
          sb.append("<h1>" + title + "<h1>\n");
          sb.append("<ul>\n");
          Iterator<Item> it=content.iterator();
          while(it.hasNext()){
              Item item=(Item)it.next();
              sb.append(item.makeHTML()); //调用 ListTray 实现完成 后的makeHTML
          }
          sb.append("</ul>\n");
          sb.append("<hr><address>"+author+"</address>");
          sb.append("</body></html>\n");
        
          return sb.toString();
      }

  }

  具体产品参与者是实现抽象产品参与者的界面(API)。扮演这个角色分别为:ListLink 类、ListTray 类、ListPage类。

  利用工厂把零件组合成产品:AbstractFactoryPatternActivity 类

  该类是界面UI展示入口,负责将抽象工厂的抽象零件和具体产品组装打包,通过传入创建的具体工厂,组装具体产品。利用outPut 输出。
  代码:

  public class AbstractFactoryPatternActivity extends Activity {
      /** Called when the activity is first created. */
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);

          ((Button) findViewById(R.id.Button01))
                  .setOnClickListener(new OnClickListener() {

                      @Override
                      public void onClick(View v) {
                          // TODO Auto-generated method stub
                          Factory factory = Factory.getFactory(ListFactory.class);
                          Link cnblogs = factory.createLink("",
                                  "http://www.cnblogs.com/terryblog");

                          Link cto = factory.createLink("51CTO",
                                  "http://terryblog.blog.51cto.com/");

                          Link csdn = factory.createLink("",
                                  "http://blog.csdn.net/terryyhl");

                          Tray cnblogsTray = factory.createTray("");
                          cnblogsTray.add(cnblogs);

                          Tray ctoTray = factory.createTray("");
                          ctoTray.add(cto);

                          Tray csdnTray = factory.createTray("");
                          csdnTray.add(csdn);

                          Page page = factory.createPage("my Blogs", "terry_龙");
                          page.add(cnblogsTray);
                          page.add(ctoTray);
                          page.add(csdnTray);

                          ((EditText) findViewById(R.id.EditText01)).setText(page
                                  .outPut());

                      }
                  });

      }
  }

  客户参与者是一个只使用抽象工厂参与者和抽象产品参与者的接口 (API)来完成 工作 的参与者。客户参与者并不知道具体零件、产品或工厂。而上面的代码就是负责做这件事。


0 0