王学岗简单工厂模式和工厂方法模式

来源:互联网 发布:高分子材料与工程知乎 编辑:程序博客网 时间:2024/05/11 02:29

我们举工作中的一个例子,老板让我集成百度地图,我完成工作了,可是老板又改注意了,让我集成高德地图,这时候怎么办,要是以前我直接拿板砖去招呼老板了!
假如我们已经实现了百度地图的集成

package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class BaiduMapView {    enum MapType{        //空白背景模式        MAP_TYPE_NONE,        //普通地图模式常量        MAP_TYPE_NORMAL,        //卫星图模式常量        MAP_TYPE_SATELLITE    }    public View getView(){        System.out.println("获取百度地图的MapView");        return null;    }    public void setMapType(MapType mapType){        System.out.println("设置了地图类型");    }}

main方法

package com.example.acer.factorypattern;/** * @author w_x_g * @time 2017/1/8 10:35 * @note ${TODO} */public class MainTest {    public static void main(String args[]){        BaiduMapView baiduMapView=new BaiduMapView();        //获取百度地图的视图        baiduMapView.getView();    }}

现在老板要我们集成高德地图,我们又按照要求集成了高德地图

package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class GaodeMapView {    enum MapType{        //空白背景模式        MAP_TYPE_NONE,        //普通地图模式常量        MAP_TYPE_NORMAL,        //卫星图模式常量        MAP_TYPE_SATELLITE    }    public View getView(){        System.out.println("获取高德地图的MapView");        return null;    }    public void setMapType(MapType mapType){        System.out.println("设置了地图类型");    }}

//修改客户端

package com.example.acer.factorypattern;/** * @author w_x_g * @time 2017/1/8 10:35 * @note ${TODO} */public class MainTest {    public static void main(String args[]){//        BaiduMapView baiduMapView=new BaiduMapView();//        //获取百度地图的视图//        baiduMapView.getView();        GaodeMapView gaodeMapView=new GaodeMapView();        gaodeMapView.getView();    }}

这时候我们发现,客户端与百度地图类耦合度非常的高,我们需要重写客户端的代码;非常之麻烦啊!
我们可以使用工厂模式来解决,本文先讲解下简单工厂模式

我们写一个接口,定义了地图的规范

package com.example.acer.factorypattern;import android.view.View;/** * 定义了地图的规范 */public interface IMap {    enum MapType{        //空白背景模式        MAP_TYPE_NONE,        //普通地图模式常量        MAP_TYPE_NORMAL,        //卫星图模式常量        MAP_TYPE_SATELLITE    }    public View getView();    public void setMapType(MapType mapType);}

高德地图与百度地图类,实现了Imap接口

package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class BaiduMapView implements IMap{    @Override    public View getView() {        System.out.println("调用了百度地图的getView");        return null;    }    @Override    public void setMapType(MapType mapType) {        System.out.println("调用了百度地图的setMapType");    }}
package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class GaodeMapView implements IMap{    public View getView(){        System.out.println("调用高德地图的getView");        return null;    }    public void setMapType(MapType mapType){        System.out.println("调用了高德地图的setMapType");    }}

工厂类我们加入了单例模式

package com.example.acer.factorypattern;/** * @author w_x_g * @time 2017/1/8 11:29 * @note ${TODO} */public class MapViewFactory {    enum MapType{        Baidu,Gaode;    }    private static MapViewFactory mMapViewFactory;    private MapViewFactory() {    }    public static MapViewFactory getInstance() {        if (mMapViewFactory == null) {            mMapViewFactory = new MapViewFactory();        }        return mMapViewFactory;    }    public IMap getMapView(MapType mapType){        IMap iMap=null;        switch (mapType){            case Gaode:                iMap=new GaodeMapView();                break;            case Baidu:                iMap=new BaiduMapView();                break;        }        return iMap;    }}

我们在看下客户端

package com.example.acer.factorypattern;/**拿到MapView的实例,不需要考虑细节 降低了地图与客户端的耦合度 不在需要new BaiduMap(); */public class MainTest {    public static void main(String args[]){       IMap iMap = MapViewFactory.getInstance().getMapView(MapViewFactory.MapType.Baidu);        iMap.getView();        iMap.setMapType(IMap.MapType.MAP_TYPE_NONE);    }}

这里写图片描述

在android中BitmapFactory,XmlPullParserFactory,CertificateFactory就是使用了简单工厂模式
简单工厂的总结:静态实例化符合我们要求的实例,核心是降低耦合

下面有这样的一种需求,百度地图新增了一项功能,但是高德地图没有该功能,这个时候IMap修改起来就很麻烦了,另外在IMap类里有很多判断,以后在增加搜狗地图还要增加判断分支;这个工厂类是公共的工厂,不能满足我们的需求。这样我们就引出了我们的工厂方法模式;

把工厂写成接口模式,针对不同的引擎创建不同的工厂
首先看下BaiduMapView和GaodeMapView类以及IMap接口

package com.example.acer.factorypattern;import android.view.View;/** * 定义了地图的规范 */public interface IMap {    enum MapType{        //空白背景模式        MAP_TYPE_NONE,        //普通地图模式常量        MAP_TYPE_NORMAL,        //卫星图模式常量        MAP_TYPE_SATELLITE    }    public View getView();    public void setMapType(MapType mapType);}
package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class BaiduMapView implements IMap{    @Override    public View getView() {        System.out.println("调用了百度地图的getView");        return null;    }    @Override    public void setMapType(MapType mapType) {        System.out.println("调用了百度地图的setMapType");    }}
package com.example.acer.factorypattern;import android.view.View;/** * @author w_x_g * @time 2017/1/8 10:28 * @note ${TODO} */public class GaodeMapView implements IMap{    public View getView(){        System.out.println("调用高德地图的getView");        return null;    }    public void setMapType(MapType mapType){        System.out.println("调用了高德地图的setMapType");    }}

一个工厂类接口和两个具体的工厂类

package com.example.acer.factorypattern;/** * 把工厂写成接口模式 */public interface IMapFactory {    IMap getMapView();}
package com.example.acer.factorypattern;/** * @author w_x_g * @time 2017/1/8 14:38 * @note ${TODO} */public class BaiduMapFactory implements IMapFactory {    @Override    public IMap getMapView() {        return new BaiduMapView();    }}
package com.example.acer.factorypattern;/** * @author w_x_g * @time 2017/1/8 14:41 * @note ${TODO} */public class GaodeMapFactory implements IMapFactory {    @Override    public IMap getMapView() {        return new GaodeMapView();    }}

main方法

package com.example.acer.factorypattern;/** * 方法工厂模式,Baidu的工厂与Gaode的工厂分开了,但又同时满足了工厂类的接口 * 百度天地图可以有自己的特殊模块,其他的地图有其它地图的特殊模块 */public class MainTest {    public static void main(String args[]){      IMapFactory iMapFactory=new BaiduMapFactory();       BaiduMapView baiduMapView= (BaiduMapView) iMapFactory.getMapView();        baiduMapView.getView();        baiduMapView.setMapType(IMap.MapType.MAP_TYPE_NONE);    }}
0 0
原创粉丝点击