博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Ap 开发 设计模式第八篇:抽象工厂模式
阅读量:5097 次
发布时间:2019-06-13

本文共 6886 字,大约阅读时间需要 22 分钟。

  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

你可能感兴趣的文章
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
我眼中的技术地图
查看>>
lc 145. Binary Tree Postorder Traversal
查看>>
在centos上开关tomcat
查看>>
android dialog使用自定义布局 设置窗体大小位置
查看>>
ionic2+ 基础
查看>>
查询消除重复行
查看>>
[leetcode]Minimum Path Sum
查看>>
内存管理 浅析 内存管理/内存优化技巧
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>
csv HTTP简单表服务器
查看>>
IO流写出到本地 D盘demoIO.txt 文本中
查看>>
Screening technology proved cost effective deal
查看>>
mysql8.0.13下载与安装图文教程
查看>>
Thrift Expected protocol id ffffff82 but got 0
查看>>
【2.2】创建博客文章模型
查看>>
Kotlin动态图
查看>>
从零开始系列之vue全家桶(1)安装前期准备nodejs+cnpm+webpack+vue-cli+vue-router
查看>>
Jsp抓取页面内容
查看>>
大三上学期软件工程作业之点餐系统(网页版)的一些心得
查看>>