设计模式之工厂模式---高上

来源:互联网 发布:java mobi文件 编辑:程序博客网 时间:2024/04/29 03:43

简单工厂模式

1.目的
工厂模式就是专门负责将大量有共同接口的类实例化,而且不必事先知道每次是要实例化哪一个类的模式。它定义一个用于创建对象的接口,由子类决定实例化哪一个类。

2 . 简单工厂模式的结构
如下图

那工厂模式主要作用是什么的,笼统地说,它是为了降低程序间的耦合性,那什么是耦合性呢?
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。耦合的强弱取决与模块间接口的复杂性、调用模块的方式以及通过界面传送数据的多少。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差。软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准。划分模块的一个准则就是高内聚低耦合。

下面我们通过一个程序示例,来了解这种工厂模式的实现,实现程序间的解耦。我们先来看看使用工厂模式之前的写法。可以方便我们比较出工厂模式发挥的作用:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ContactDaoImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IContactDao</span> {</span>    <span class="hljs-comment">//这是我们的数据实体类,是需要调用者调用的</span>    <span class="hljs-comment">//数据类中的getData方法封装了一些数据</span>    <span class="hljs-keyword">public</span> List<Contact> <span class="hljs-title">getData</span>() {        List<Contact> data = <span class="hljs-keyword">new</span> ArrayList<Contact>();        data.add(<span class="hljs-keyword">new</span> Contact(R.drawable.headimage01, <span class="hljs-string">"Jack"</span>, <span class="hljs-string">"13800138001"</span>));        data.add(<span class="hljs-keyword">new</span> Contact(R.drawable.headimage02, <span class="hljs-string">"Alex"</span>, <span class="hljs-string">"13800138002"</span>));        data.add(<span class="hljs-keyword">new</span> Contact(R.drawable.headimage12, <span class="hljs-string">"Jason"</span>, <span class="hljs-string">"13800138008"</span>));        data.add(<span class="hljs-keyword">new</span> Contact(R.drawable.headimage15, <span class="hljs-string">"Mike"</span>, <span class="hljs-string">"13800138009"</span>));        <span class="hljs-keyword">return</span> data;    }}</code><ul class="pre-numbering"><li></li></ul>

下面我们来看看调用者是如何调用数据的:

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span>    <span class="hljs-keyword">private</span> List<Contact> contacts;    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    <span class="hljs-comment">//解耦前的写法,没有用到工厂模式</span>    ContactDaoImpl a = <span class="hljs-keyword">new</span> ContactDaoImpl();    contacts = a.getData();    }}</code><ul class="pre-numbering"><li></li></ul>

我们可以看到当我们需要调用数据时,是要直接new出数据类的对象的。

下面着重注意这段话:

那好现在我们出现了问题,当我们有很多类都要调用数据类时,我们要在每个类都要new出数据类的对象,但重点并不是这!当我们的数据发生改变时,数据类需要更换,此时问题就比较严重了,我们就要在每个调用数据类的地方,都需要更改成新的数据类,这会很浪费我们的时间。所以我们要用工厂模式来解开这种耦合。


实现思路:

1.在接口中定义数据类中封装数据的方法getdata(),这是为了更方便的管理我们数据类中的方法。

2.然后在写一个工厂类,类中定义一个创建我们数据类对象静态方法newInstance(),(注意此方法的返回值类型是接口类型),此方法这是为了方便管理我们的数据类,也为了更方便地创建数据类对象。

好了现在我们在原有代码基础上,新建一个接口IContactDao:

<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> IContactDao {    <span class="hljs-comment">//定义数据类中封装数据的方法getdata(),所有我们要用到数据类都要实现此接口重写getData()方法。这是为了更方便的管理我们数据类中的方法。</span>    List<Contact> getData();}</code><ul class="pre-numbering"><li></li></ul>

下面我们再创建一个工厂类ContactDaoFactory:

<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> ContactDaoFactory {    <span class="hljs-comment">//私有构造方法防止其他人创建我们的工厂对象</span>    <span class="hljs-keyword">private</span> <span class="hljs-title">ContactDaoFactory</span>() {    }    <span class="hljs-comment">//创建我们数据类对象静态方法newInstance(),注意此方法的返回值是接口类型的,也就是创建出来的对象都必须是实现了IContactDao接口的</span>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IContactDao <span class="hljs-title">newInstance</span>() {        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ContactDaoImpl1();    }}</code><ul class="pre-numbering"><li></li></ul>

好那最后我们来观察一下调用者调用我们数据类的写法;

<code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Activity</span> {</span>    <span class="hljs-keyword">private</span> List<Contact> contacts;    <span class="hljs-annotation">@Override</span>    <span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span>(Bundle savedInstanceState) {        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    <span class="hljs-comment">//使用工厂模式前的写法</span>    ContactDaoImpl a = <span class="hljs-keyword">new</span> ContactDaoImpl();    contacts = a.getData();    <span class="hljs-comment">//使用工厂模式的写法</span>    IContactDao dao = ContactDaoFactory.newInstance();    contacts = dao.getData();    }}   </code><ul class="pre-numbering"><li></li></ul>

看到了吧使用工厂模式后在调用者中我们完全看不到创建出来的是哪个数据类对象,也不必去关心到底创建的哪个数据实体类。


当我们的业务需求改变了,需要新的数据了,

1.第一步:让数据类实现IContactDao接口,在getdata中填入我们的新数据
2.第二步:在工厂类中直接将newInstance()方法创建出的对象改成我们的新的数据类ContactDaoImpl2就好了

<code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IContactDao <span class="hljs-title">newInstance</span>() {       <span class="hljs-comment">//在此处换成新的数据类 </span>       <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ContactDaoImpl2(); }</code><ul class="pre-numbering"><li></li></ul>

好了这样就完成了,我们根本不用去修改调用者类中的代码,当有很多调用者调用数据类时,这种模式是很实用的,谢谢大家,有不足之处欢迎指正。

0 0