Android Ap 开发 设计模式第八篇:抽象工厂模式

it2022-05-09  26

  Abstract Factory Pattern

模式解读

  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)来完成 工作 的参与者。客户参与者并不知道具体零件、产品或工厂。而上面的代码就是负责做这件事。

 

运行结果:

 

源码下载:

 抽象工厂模式

 

  再发个求职信息:

  求职android(可胜任Framework及 以上工作。一年半经验) 、Windows Phone 7(软件、XNA) 开发工作。

 

转载于:https://www.cnblogs.com/TerryBlog/archive/2011/07/25/2116617.html

相关资源:数据结构—成绩单生成器

最新回复(0)