美文网首页奔跑吧,JAVA!Android高级技术软件生涯
Android 架构师之路6 设计模式之工厂模式

Android 架构师之路6 设计模式之工厂模式

作者: 香沙小熊 | 来源:发表于2018-01-22 20:06 被阅读200次

    Android 架构师之路 目录

    前言

    工厂模式中,重要的是工厂类,而不是产品类。产品类可以是多种形式,多层继承或者是单个类都是可以的。但要明确的,工厂模式的接口只会返回一种类型的实例,这是在设计产品类的时候需要注意的,最好是有父类或者共同实现的接口。
    使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。
    工厂模式返回的实例可以不是新创建的,返回由工厂创建好的实例也是可以的。

    工厂模式主要是为创建对象提供了接口。工厂模式按照《Java与模式》中的提法分为三类:

    1. 简单工厂模式(Simple Factory)
    2. 工厂方法模式(Factory Method)
    3. 抽象工厂模式(Abstract Factory)

    1、工厂模式 - 简单工厂模式

    简单工厂优点:客户端可以免除直接创建产品对象的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割。

    1.1、 简单工厂模式UML图
    简单工厂模式UML图
    1.2、 代码实现
    定义接口
    /**
     * 地图规范
     * @author Dream
     *
     */
    public interface IMapView {
        enum MapType {
            // 空白背景模式常量
            MAP_TYPE_NONE,
            // 普通地图模式常量
            MAP_TYPE_NORMAL,
            // 卫星图模式常量
            MAP_TYPE_SATELLITE
        }
    
        public View getView();
    
        public void setMapType(MapType mapType);
    }
    
    实现接口
    public class BaiduMapView implements IMapView {
    
        @Override
        public View getView() {
            System.out.println("调用了百度地图的getView");
            return null;
        }
    
        @Override
        public void setMapType(MapType mapType) {
            System.out.println("调用了百度地图的setMapType");
        }
    
    }
    
    
    public class GaodeMapView implements IMapView {
    
        @Override
        public View getView() {
            System.out.println("调用了高德地图的getView");
            return null;
        }
    
        @Override
        public void setMapType(MapType mapType) {
            System.out.println("调用了高德地图的setMapType");
        }
    
    }
    
    
    创建工厂类
    public class MapViewFactory {
        
        enum MapType{
            Baidu,
            Gaode
        }
        
        //使用上一节课的内容---单例模式
        //懒汉式
        private static MapViewFactory mapViewFactory;
        
        private MapViewFactory(){
            
        }
        
        public static MapViewFactory getInstance(){
            if(mapViewFactory == null){
                mapViewFactory = new MapViewFactory();
                ArrayList<String> list = new ArrayList<String>();
                HashSet<String> hashSet = new HashSet<String>();
            }
            return mapViewFactory;
        }
        
        public IMapView getMapView(MapType mapType){
            IMapView mapView = null;
            switch (mapType) {
            case Baidu:
                mapView = new BaiduMapView();
                break;
            case Gaode:
                mapView = new GaodeMapView();
                break;
            }
            return mapView;
        }
        
    }
    
    调用主函数
    public class SimpleTest {
    
        public static void main(String[] args) {
            // 客户端和我们的地图模块耦合度大大降低了
            IMapView mapView = MapViewFactory.getInstance().getMapView(
                    MapViewFactory.MapType.Baidu);
            mapView.getView();
            mapView.setMapType(IMapView.MapType.MAP_TYPE_NONE);
        }
    
    }
    
    
    运行结果
    获得百度地图MapView
    设置了高德地图类型
    获得高德地图MapView
    设置了高德地图类型
    
    1.3、Android源码中使用
    Android中简单工厂--BitmapFactory,XmlPullParserFactory,CertificateFactory
    

    2、工厂模式 - 工厂方法模式

    工厂方法模式:把对象的实现延迟到子类完成
    工厂方法优点:允许系统在不修改具体工厂角色的情况下引进新产品。

    2.1、 工厂方法模式UML图
    工厂方法模式UML图
    2.2、 代码实现
    产品接口与实现(Mapview)
    //接口
    public abstract class IMapView {
        public abstract void onStart();
    
        public abstract void onResume();
    
        public abstract void onDestory();
    }
    
    public class BaiduMapView extends IMapView {
    
        @Override
        public void onStart() {
            System.out.println("百度地图onStart");
        }
    
        @Override
        public void onResume() {
            System.out.println("百度地图onResume");
        }
    
        @Override
        public void onDestory() {
            System.out.println("百度地图onDestory");
        }
    
    }
    
    public class GaodeMapView extends IMapView {
    
        @Override
        public void onStart() {
            System.out.println("高德地图onStart");
        }
    
        @Override
        public void onResume() {
            System.out.println("高德地图onResume");
    
        }
    
        @Override
        public void onDestory() {
            System.out.println("高德地图onResume");
        }
    
    }
    
    抽象工厂
    //抽象
    public abstract class AbsMapFactory {
        // 我只定义标准
        public abstract <T extends IMapView> T createMapView(Class<T> clzz);
    }
    
    
    实现工厂
    public class DefaultMapFactory extends AbsMapFactory {
    
        private static DefaultMapFactory defaultMapFactory;
    
        private DefaultMapFactory() {
        }
    
        public static DefaultMapFactory getInstance(){
            if(defaultMapFactory == null){
                defaultMapFactory = new DefaultMapFactory();
            }
            return defaultMapFactory;
        }
    
    
        @Override
        public <T extends IMapView> T createMapView(Class<T> clzz) {
            try {
                // 反射
                return clzz.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    
    调用主函数
    public class TestClient {
        
        public static void main(String[] args) {
            //工厂方法模式
            AbsMapFactory factory = DefaultMapFactory.getInstance();
            BaiduMapView mapView = factory.createMapView(BaiduMapView.class);
            mapView.onStart();
    
        }
        
    }
    
    
    运行结果
    百度地图onStart
    
    2.2、 Java或Android中源码运用

    分析List集合、Set集合、Map集合 源码
    lterator:遍历集合工厂方法抽象
    Itr:具体的工厂实现类

    lterator-> 抽象(工厂方法抽象) -->AdsMapFactory
    Itr ->具体实现类->DefaultMapFactory
    AbstractList-> 抽象 -->ImapView

          ArrayList-> 实现类-->  BaiduMapView
    

    3、工厂模式 - 抽象工厂模式

    为了增加导航模块、全景图口快、定位模块而不仅仅是地图模块引入抽象工厂模式 (一组类要求相同约束)
    抽象工厂优点:向客户端提供一个接口,使得客户端在不必指定产品具体类型的情况下,创建多个产品族中的产品对象

    3.1、 抽象工厂模式UML图
    抽象工厂模式UML图
    3.2、 代码实现
    抽象工厂
    public abstract class AbsMapFactory {
    
        public abstract AbsMapView createMapView();
    
        public abstract AbsMapNavigation createMapNavigation();
    
        public abstract AbsMapLocation createMapLocation();
    }
    
    
    各种具体工厂
    public class GaodeMapFactory extends AbsMapFactory {
    
        @Override
        public AbsMapView createMapView() {
            return new GaodeMapView();
        }
    
        @Override
        public AbsMapNavigation createMapNavigation() {
            return new GaodeMapNavigation();
        }
    
        @Override
        public AbsMapLocation createMapLocation() {
            return new GaodeMapLocation();
        }
    
    }
    
    public class BaiduMapFactory extends AbsMapFactory {
    
        @Override
        public AbsMapView createMapView() {
    
            return  new BaiduMapView();
        }
    
        @Override
        public AbsMapNavigation createMapNavigation() {
    
            return new BaiduMapNavigation();
        }
    
        @Override
        public AbsMapLocation createMapLocation() {
            return new BaiduMapLocation();
        }
    
    }
    
    初始化工厂
    public class DefaultFactory {
    
    
        //使用反射
        public static  <T extends AbsMapFactory> T creatProduct(Class<T> clz){
            AbsMapFactory api =null;
            try {
                api =(AbsMapFactory) Class.forName(clz.getName()).newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            return (T)api;
        }
    
    }
    
    
    工厂内各产品

    定位产品

    public abstract class AbsMapLocation {
        
        /**
         * 定位
         */
        public abstract void location();
    }
    
    
    public class BaiduMapLocation extends AbsMapLocation {
    
        @Override
        public void location() {
            System.out.println("百度地图定位...");
        }
    
    }
    
    public class GaodeMapLocation extends AbsMapLocation {
    
        @Override
        public void location() {
            System.out.println("高德地图定位...");
        }
    
    }
    
    

    地图产品

    public abstract class AbsMapView {
        
        /**
         * Result for IActivityManager.startActivity: an error where the
         * start had to be canceled.
         * @hide
         */
        public abstract void onStart();
    
        public abstract void onResume();
    
        public abstract void onDestory();
    }
    
    
    public class BaiduMapView extends AbsMapView {
    
        
        @Override
        public void onStart() {
            System.out.println("百度地图调用了onStart");
        }
    
        @Override
        public void onResume() {
            System.out.println("百度地图调用了onResume");
        }
    
        @Override
        public void onDestory() {
            System.out.println("百度地图调用了onDestory");
        }
    
    }
    
    public class GaodeMapView extends AbsMapView {
    
        @Override
        public void onStart() {
            System.out.println("高德地图调用了onStart");
        }
    
        @Override
        public void onResume() {
            System.out.println("高德地图调用了onResume");
        }
    
        @Override
        public void onDestory() {
            System.out.println("高德地图调用了onDestory");
        }
    
    }
    

    导航产品

    public abstract class AbsMapNavigation {
        
        /**
         * 路线规划
         */
        public abstract void turnByTurn();
        
        //......很多功能方法
    }
    
    public class BaiduMapNavigation extends AbsMapNavigation {
    
        @Override
        public void turnByTurn() {
            System.out.println("百度地图导航路线规划");
        }
    
    }
    
    public class GaodeMapNavigation extends AbsMapNavigation {
    
        @Override
        public void turnByTurn() {
            System.out.println("高德地图导航功能路线规划");
        }
    
    }
    
    
    调用主函数
    
    
    public class Test {
        
        public static void main(String[] args) {
            //直接初始化某地图
            AbsMapFactory factory = new BaiduMapFactory();
            factory.createMapView().onStart();
            factory.createMapLocation().location();
    
            //反射初始化某地图
            AbsMapFactory factory2 =  DefaultFactory.creatProduct(GaodeMapFactory.class);
            factory2.createMapView().onStart();
            factory2.createMapLocation().location();
        }
    }
    
    运行结果
    百度地图调用了onStart
    百度地图定位...
    高德地图调用了onStart
    高德地图定位...
    
    3.3、 Android源码中使用

    Activity、Service --- AbsMapView或者AbsMapNavgation
    我们自定义的Activity(如BaseActivity)、Service ---BaiduMapView 或 BaiduMapNavgation
    ActivityManager、ServiceManager --- 类似于我们通常所说的AbsMapFactory

    总结:

    简单工厂 : 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)
    工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)
    抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)

    以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

    相关文章

      网友评论

        本文标题:Android 架构师之路6 设计模式之工厂模式

        本文链接:https://www.haomeiwen.com/subject/qacefxtx.html