封装需求的变更-策略模式和工厂模式(一)

软件开发,需求变更是家常便饭,前期调研不仔细,app做好了,客户不满意,领导一句话,变更;客户觉得那种操作习惯好一些,变更;地图不显示不完全,换地图。

既然避免不了,我们就应该把需要变动的隔离出来,不变的放另外的地方。

         以下通过一个加载Google和apple地图的例子,来试图说明如何封装需求的变更,各位看官看完后,还请大家留下你们宝贵的意见。

         加载苹果地图很方便,官方都有文档,主要是MapKit框架,这个就不多说了,好,我们把代码集成到工程里面去:

    

CGRect rect=[UIScreen mainScreen].bounds;
    _mapView=[[MKMapView alloc]initWithFrame:rect];
    [self.view addSubview:_mapView];
    //设置代理
    _mapView.delegate=self;
    
    //请求定位服务
    _locationManager=[[CLLocationManager alloc]init];
    if(![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!=kCLAuthorizationStatusAuthorizedWhenInUse){
        [_locationManager requestWhenInUseAuthorization];
    }
    
    //用户位置追踪(用户位置追踪用于标记用户当前位置,此时会调用定位服务)
    _mapView.userTrackingMode=MKUserTrackingModeFollow;
    
    //设置地图类型
    _mapView.mapType=MKMapTypeStandard;
    
    //添加大头针
    [self addAnnotation];

    

    一切都很完美,可是突然领导对我们说,苹果地图不好用,我们要用Google的,好,我们把上面的代码注释掉,然后到Google的官网上查api,然后再集成。

    好吧,Google地图和苹果地图完全不一样,代码重新写,结构变了:


    GoogleMapEntry *entry = [[GoogleMapEntry alloc] init];

   if (object!=nil && [object isKindOfClass:[NSDictionary class]]) {

        [GMSServices provideAPIKey:@"AIzaSyCX4TM8eqps-FUKHY3bz1vVQK1PDzn_bGU"];

    }

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86 longitude:151.20 zoom:6];

    [entry setMapView:[GMSMapView mapWithFrame:CGRectZero camera:camera]];

    ((GMSMapView *)entry.mapView).myLocationEnabled =YES;

    。。。。。

   然后改调用的地方,全文搜索,改了一两天,终于改好了,问题又来了,由于代码不兼容,运行的时候老是报方法找不到。。

   然后,过一段时间,领导说,你还是改成百度地图吧,Google地图在中国不好用。。大哭


   我们有更好的方法吗?

   我们通过对比苹果地图和Google地图,发现其实要显示一个地图呀,两个api有类似的方法,初始化地图并显示和添加大头针,

   于是,我们提出这两个方法,写到基类里面:


#import <Foundation/Foundation.h>


@interface SuperMapThird : NSObject


@property (nonatomic,retain) id mapView;

+(id)InitMapThirdUserInfo:(id)object;


/**

  添加大头针

  *

  @param userInfo key: Latitude,  Longitude

  */

-(void)addAnnotationView:(id)userInfo;

@end


   苹果地图继承这两个基类:

#import "SuperMapThird.h"


@interface AppleMapEntry : SuperMapThird


@end


#import "AppleMapEntry.h"

#import <MapKit/MapKit.h>

#import "MKMapView+MapViewUtil.h"


@implementation AppleMapEntry


+(id)InitMapThirdUserInfo:(id)object {

    AppleMapEntry *entry = [[AppleMapEntry alloc] init];

    [entry setMapView:[[MKMapView alloc] initWithFrame:CGRectMake(10,110, 300,DEV_MAIN_SCREEN-110-50-40-64)]];

    MKMapView *mapView = entry.mapView;

    

    。。。。

    

    return entry;

}


-(void)addAnnotationView:(id)userInfo {

    if (userInfo!=nil && [userInfo isKindOfClass:[NSDictionary class]]) {

        CLLocationDegrees latitude = [[userInfo objectForKey:@"Latitude"] doubleValue];

        CLLocationDegrees longitude = [[userInfo objectForKey:@"Longitude"] doubleValue];

        MKMapView *mapView = (MKMapView *)self.mapView;

        CLLocationCoordinate2D coordinate;

        coordinate.latitude = latitude;

        coordinate.longitude = longitude;

        MKPointAnnotation *ann = [[MKPointAnnotation alloc] init];

        ann.coordinate = coordinate;

        //[ann setTitle:stDetail.StoreName];

        //[ann setTitle:@"购物好去处"];

        //触发viewForAnnotation

        [mapView addAnnotation:ann];

    }

}


@end


谷歌地图也继承这个类:

#import <Foundation/Foundation.h>

#import <GoogleMaps/GoogleMaps.h>

#import "SuperMapThird.h"


@interface GoogleMapEntry : SuperMapThird


@end


#import "GoogleMapEntry.h"


@implementation GoogleMapEntry


+(id)InitMapThirdUserInfo:(id)object {

   GoogleMapEntry *entry = [[GoogleMapEntry alloc] init];

   。。。

   return entry;

}


-(void)addAnnotationView:(id)userInfo {

   if (userInfo!=nil && [userInfo isKindOfClass:[NSDictionary class]]) {

       CLLocationDegrees latitude = [[userInfo objectForKey:@"Latitude"] doubleValue];

       CLLocationDegrees longitude = [[userInfo objectForKey:@"Longitude"] doubleValue];

       GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:latitude longitude:longitude zoom:6];

       GMSMapView *gsmMap = self.mapView;

       gsmMap = [GMSMapView mapWithFrame:CGRectZero camera:camera];

       gsmMap.myLocationEnabled = YES;

        //create a marker in the center of the map

       GMSMarker *marker = [[GMSMarker alloc]init];

       marker.position = CLLocationCoordinate2DMake(-33.86,151.20);   //地图显示的大头针做坐标

       marker.title = @"Sydney";

       marker.snippet = @"Australia";

       marker.map = self.mapView;

   }

}


@end



然后,我们通过一个工厂来创建不同的地图实例:

#import <Foundation/Foundation.h>

#import "SuperMapThird.h"


@interface MapThirdFactory : NSObject


+(SuperMapThird *)getMapEntry:(NSInteger)type userInf:(id)object;


@end


#import "MapThirdFactory.h"

#import "MapThirdDefine.h"


#import "AppleMapEntry.h"

#import "GoogleMapEntry.h"


@implementation MapThirdFactory


+(SuperMapThird *)getMapEntry:(NSInteger)type userInf:(id)object {

    SuperMapThird *entry = nil;

    switch (type) {

//苹果地图

        case MAPTHIRDAPPLE:

            entry = [AppleMapEntry InitMapThirdUserInfo:object];

            break;

        default:

//默认返回谷歌地图

            entry = [GoogleMapEntry InitMapThirdUserInfo:object];

            break;

    }

    return entry;

}


@end


如此,现在app调用只跟工厂类有关了

    MapThirdManage *manage = [[MapThirdManage alloc] init];

    [manage setMapThirdEntry:[MapThirdFactory getMapEntry:type userInf:object]];


如果领导说我想还是用百度地图吧,好吧,我们重新写一个类,继承SuperMapThird,然后实现他的两个方法,

最后在app的调用里面把type改成所定义的百度地图的类型,由于初始化地图和添加大头针都是基类的方法,

跟子类实现无关,所以我们不需要全文搜索了,嘿嘿。。。








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值