葡京网上娱乐场设计模式 – 策略模式

前言:

  先任模式, 把他同外的名还忘了, 来探视问题 和 设计思路.
为底要这么做. 

1.Notification(通知)

自从Notification给引入之后,苹果就是没完没了的更新优化,但这些更新优化只是小打小闹,直至现在iOS
10开端确实的展开大改重构,这吃开发者也体会到UserNotifications的易用,功能吗换得深强大。

  • iOS 9 以前的关照

    1.当调用方法时,有些措施吃人口蛮麻烦分,容易写错方法,这给开发者有时候很郁闷。

    2.行使在运行时与非运行时捕获通知的门径还免同等。

    3.使在前台时,是力不从心直接展示远程通知,还需要更加处理。

    4.曾起的通告是勿能够创新的,内容来时凡免克改变的,并且只有大概文本展示方式,扩展性根本不是很好。

  • iOS 10 开始之关照

    1.有相关通知为合并到了UserNotifications.framework框架中。

    2.增了撤回、更新、中途还好改通知之始末。

    3.通告非以是简约的文本了,可以进入视频、图片,自定义通知之展示等等。

    4.iOS
    10针锋相对之前的打招呼来说更加好用易于管理,并且进行了大优化,对于开发者来说是平等起善事。

    5.iOS
    10上马对权力问题开展了优化,申请权限就比较简单了(本地及长途通知并在一个方法吃)。

  • iOS 10 通知上相关资料:

[UserNotifications:

场景:

  有同等贱商家, 里面有一个店员, 售货员当然是如果出卖东西的啊,
客户上买完东西, 找售货员结账, 那售货员得理解一共多少钱吧?

一. 初步设计

  商品类:

package org.elvin.strategy;

/***/
public class Goods {
    /**
     * 商品名
     */
    private String name;

    /**
     * 商品价格
     */
    private Long Price;

    public Goods() { }

    public Goods(String name, Long price) {
        this.name = name;
        Price = price;
    }

    //region getter / setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getPrice() {
        return Price;
    }

    public void setPrice(Long price) {
        Price = price;
    }
    //endregion
}

 

鉴于价位我下的是 Long 类型, 所以, 要来一个易输出的方法.

package org.elvin.strategy;

import java.text.MessageFormat;

public class MoneyUtils {
    public static String getYuan(Long money){
        Long yuan = money / 100;
        Long jiao = money % 100 /  10;
        Long fen = money % 10;

        return MessageFormat.format("{0}.{1}{2}", yuan, jiao , fen );
    }
}

售货员:

package org.elvin.strategy;

import org.elvin.strategy.calculator.*;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * 环境角色(Context)*/
public class Seller {

    /**
     * 姓名
     */
    private String name;

    /**
     * 编号
     */
    private String code;

    //region getter / setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    //endregion

    /**
     * 售卖商品
     */
    public void sellGoods(List<Goods> goods){
        Long sum = 0L;
        for (Goods good : goods) {
            sum += good.getPrice();
        }
        System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
    }

    @Test
    public void func1(){
        List<Goods> goods = new ArrayList<>();
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("饼干", 250L));
        goods.add(new Goods("辣条", 300L));

        sellGoods(goods);
    }
}

来拘禁一下算结果:

葡京网上娱乐场 1

获得结果了, 没啥毛病, 挺好. 

今老板娘了生日, 突然想到, 要无苟更店里为个走, 来个优惠活动,
有些商品减价销售. 

明业主了生日, 老板娘说, 老娘高兴, 你减价销售, 明天自己来单免单销售.

那本咋办啊? 明天过后, 价格一定还要要过来至正常价格.  what the fuck! 

Seller类写好了, 难道我于里面加几独计算方法? 

加进去貌似可以缓解当下题材, 但是, 后天如果业主的岳父过生日也? 咋干?

 

Ok, 到此地, 差不多, 需要请出今天之百般神 : 策略模式.
让他来拉咱缓解是题材吧.

 

二. 设计改造

对售货员来说, 她得清楚, 今天欠怎么算价格, 是特惠还是不优惠,
或者是充满小钱, 送东西啊的. 

那, 将这些优惠或者说价格的计量方法抽象出来, 成为一个接口或者抽象类. 

让优惠或者未优惠实现或者连续他.

实现方式:

这边, 我将他抽象为一个接口

package org.elvin.strategy.calculator;

import org.elvin.strategy.Goods;

import java.util.List;

/**
 * 抽象策略角色(Strategy)
 * 优惠接口
*/
public interface PreferentialPrice {
    public void getPrice(List<Goods> goods);
}

PreferentialPrice 需要作为一个属性,出现在 Seller 类中.

在Seller中加入

    /**
     * 计算优惠后的价格
     * 抽象角色, 次角色给出所有具体策略类所需的接口
     */
    private PreferentialPrice preferentialPrice;

    public PreferentialPrice getPreferentialPrice() {
        return preferentialPrice;
    }

    public void setPreferentialPrice(PreferentialPrice preferentialPrice) {
        this.preferentialPrice = preferentialPrice;
    }

 

此间提供三种植计算方法:

  1. 好端端艺术

    /**

    • 切切实实策略角色(ConcreteStrategy)
      */
      public class NoPreferential implements PreferentialPrice {

      @Override
      public void getPrice(List goods) {

       Long sum = 0L;
       for (Goods good : goods) {
           sum += good.getPrice();
       }
       System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
      

      }
      }

  2. 免单方式

    /**

    • 现实政策角色(ConcreteStrategy)
      */
      public class Free implements PreferentialPrice {
      @Override
      public void getPrice(List goods) {

       System.out.println("免单, 不要钱 !");
      

      }
      }

  3. 有些优惠方式

    /**

    • 切实政策角色(ConcreteStrategy)
      */
      public class ReduceSomeGoods implements PreferentialPrice {

      @Override
      public void getPrice(List goods) {

       Long sum = 0L;
       for (Goods good : goods) {
           switch (good.getName()) {
               case "泡面":
                   sum += good.getPrice() - 50L;
                   break;
      
               case "火腿":
                   sum += good.getPrice() - 20L;
                   break;
      
               case "鸡蛋":
                   sum += good.getPrice() - 10L;
                   break;
      
               default:
                   sum += good.getPrice();
                   break;
           }
       }
       System.out.println("应付款: " + MoneyUtils.getYuan(sum) + " 元");
      

      }
      }

  

 将Seller类中, 计算的计修改一下:

    public void sellGoods(List<Goods> goods){
        if(preferentialPrice == null){
            setPreferentialPrice(new NoPreferential());
        }
        preferentialPrice.getPrice(goods);
    }

于盘算的时节, 如果没有传到优惠, 则默认使用无优惠方式

再次拘留测试方法:

    @Test
    public void func1(){
        List<Goods> goods = new ArrayList<>();
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("泡面", 550L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("火腿", 150L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("鸡蛋", 70L));
        goods.add(new Goods("饼干", 250L));
        goods.add(new Goods("辣条", 300L));

        setPreferentialPrice(new Free());
        sellGoods(goods);
        System.out.println("-----------------------");
        setPreferentialPrice(new ReduceSomeGoods());
        sellGoods(goods);
        System.out.println("-----------------------");
        setPreferentialPrice(new NoPreferential());
        sellGoods(goods);
    }

结果:

  葡京网上娱乐场 2

策略模式作为同样种植对象行为模式, 在此处应该还是体现到了吧.

那么总结一下?给个非便于理解(网上抄的):

  策略模式属于对象的所作所为模式。其用意是针对一组算法,将各个一个算法封装到有协同接口的独立的接近吃,从而使它可以相互替换。策略模式使算法可以当无影响及客户端的情景下发生变化。

说的比较空虚, 来只具体的吧:

  一绝妙哥哥喜欢约妹子, 那咋约出来吗? 不是有所的胞妹都爱好用看电影吧.
那针对不同的妹妹, 使用不同之道来约. 约好看录像之胞妹看录像,
约喜欢吃小吃的阿妹吃小吃.

这就是说用, 看录像, 吹海风…… 等等, 这些手法,
目的都是以为妹妹做他女对象(这里不讨论时间). 目的不变换, 手段层出不穷.
这些主意, 就可以了解呢不同的 strategy. 

 

经地方的例子, 可以望, 具体的算法和算法之间从来不因关系,
都是同等之(平等性), 可以彼此替换的. 那以运行的下,
每次都不得不利用同一栽(唯一性). 

苹果官方文档](https://link.jianshu.com?t=https%3A%2F%2Fdeveloper.apple.com%2Freference%2Fusernotifications)

苹果官方看来频1

苹果官方看来频2

苹果官方视频3
活久见的重构 – iOS 10 UserNotifications
框架解析
WWDC2016 Session笔记 – iOS 10
推送Notification新特性

2.ATS的问题

iOS
9中默认HTTP的大网是休引进应用的,当然我们吧可以将NSAllowsArbitraryLoads设置为YES禁用ATS。不过iOS
10由2017年1月1日自苹果不允我们由此是法子跳了ATS,也就是说强制我们之所以HTTPS,如果无这样的话提交App可能会见给拒。但是咱好透过NSExceptionDomains来针对特定的域名开放HTTP可以好通过核对。

参照学习文章如下:
关于 iOS 10 中 ATS
的问题

3.iOS 10 隐私权限设置

iOS 10
开始针对隐私权限更加严酷,如果您无安装就见面一直倒,现在广大赶上崩溃问题了,一般解决办法都是于info.plist文本添加对应的KeyValue就可了。

以上Value价值,圈出的红线部分的仿是展示给用户看之,需要自己加上规范之唤醒说明,不能够吧空。目前解决办法基本都一模一样,参考学习文章如下:
兼容iOS
10:配置获取隐私数据权限声明

4.Xcode 8 运行一堆积没因此底logs解决办法

达成图我们看看,自己新建的一个工程啥呢尚未涉及就打印一堆积烂七八糟的物,我觉着是相应是Xcode 8的题目,具体也远非仔细研究,解决办法是装OS_ACTIVITY_MODE : disable如下图:

相关题材接二连三:
stackoverflow问答

5.iOS 10 UIStatusBar方法过期:

以我们出中生或就此到UIStatusBar一对属性,在iOS 10
中这些措施都过期了,如果你的档次被中之言辞虽得要适配。上面的图样也克觉察,如果当iOS
10挨公待用preferredStatusBar按部就班这样:

//iOS 10 
- (UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleDefault;
}

6.iOS 10 UICollectionView 性能优化

随着开发者对UICollectionView的深信,项目面临之所以之地方也比多,但是还是存在部分题材,比如偶尔会卡顿、加载慢等。所以iOS
10
UICollectionView逾的优化,因为叙述起来比较复杂耗费时间,在此只提供学习参考文章如下:
WWDC2016 Session笔记 – iOS 10
UICollectionView新特性

7.iOS 10 UIColor 新增方法

以下是法定文档的说明:

Most graphics frameworks throughout the system, including Core Graphics,
Core Image, Metal, and AVFoundation, have substantially improved support
for extended-range pixel formats and wide-gamut color spaces. By
extending this behavior throughout the entire graphics stack, it is
easier than ever to support devices with a wide color display. In
addition, UIKit standardizes on working in a new extended sRGB color
space, making it easy to mix sRGB colors with colors in other, wider
color gamuts without a significant performance penalty.

Here are some best practices to adopt as you start working with Wide
Color.

  • In iOS 10, the UIColor class uses the extended sRGB color space and
    its initializers no longer clamp raw component values to between 0.0
    and 1.0. If your app relies on UIKit to clamp component values
    (whether you’re creating a color or asking a color for its component
    values), you need to change your app’s behavior when you link
    against iOS 10.
  • When performing custom drawing in a UIView on an iPad Pro (9.7
    inch), the underlying drawing environment is configured with an
    extended sRGB color space.
  • If your app renders custom image objects, use the new
    UIGraphicsImageRenderer class to control whether the destination
    bitmap is created using an extended-range or standard-range format.
  • If you are performing your own image processing on wide-gamut
    devices using a lower level API, such as Core Graphics or Metal, you
    should use an extended range color space and a pixel format that
    supports 16-bit floating-point component values. When clamping of
    color values is necessary, you should do so explicitly.
  • Core Graphics, Core Image, and Metal Performance Shaders provide new
    options for easily converting colors and images between color
    spaces.

坐事先我们且是为此RGB来装颜色,反正用起来呢不是专门多样化,这次新增的道应该就是是一个弥补吧。所以于iOS
10
苹果官方建议我们以sRGB,因为其性能再好,色彩更丰富。如果你协调吗UIColor写了同模拟分类的语句也可尝替换为sRGBUIColor类吃新增了片只Api如下:

+ (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

- (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);

8.iOS 10 UITextContentType

// The textContentType property is to provide the keyboard with extra information about the semantic intent of the text document.

@property(nonatomic,copy) UITextContentType textContentType NS_AVAILABLE_IOS(10_0); // default is nil

在iOS 10
UITextField添加了textContentType枚举,指示文本输入区域所愿意之语义意义。

应用此属性可以让键盘和体系信息,关于用户输入的始末之预料的语义意义。例如,您得指定一个文书字段,用户填写收到一模一样封电子邮件确认uitextcontenttypeemailaddress。当您提供关于您要用户以文书输入区域被输入的内容的消息经常,系统可于一些情况下活动选择相当的键盘,并提高键盘修正和积极和其余文件输入会的构成。

9.iOS 10 字体随着手机系统字体而反

当我们手机系统字体改变了今后,那咱们Applabel否会见就一起转,这得我们刻画过多代码来更为处理才贯彻,但是iOS
10
提供了这样的习性adjustsFontForContentSizeCategory来安。因为从没真机,具体实际操作还从来不去贯彻,如果知道错帮忙指正。

  UILabel *myLabel = [UILabel new];

   /*
    UIFont 的preferredFontForTextStyle: 意思是指定一个样式,并让字体大小符合用户设定的字体大小。
   */
    myLabel.font =[UIFont preferredFontForTextStyle: UIFontTextStyleHeadline];

 /*
 Indicates whether the corresponding element should automatically update its font when the device’s UIContentSizeCategory is changed.
 For this property to take effect, the element’s font must be a font vended using +preferredFontForTextStyle: or +preferredFontForTextStyle:compatibleWithTraitCollection: with a valid UIFontTextStyle.
 */
     //是否更新字体的变化
    myLabel.adjustsFontForContentSizeCategory = YES;

10.iOS 10 UIScrollView新增refreshControl

iOS 10 以后如是持续UIScrollView那即便支持刷新功能:

@property (nonatomic, strong, nullable) UIRefreshControl *refreshControl NS_AVAILABLE_IOS(10_0) __TVOS_PROHIBITED;

11.iOS 10 判断系版本是姿势

看清系版本是我们常常采取的,尤其是今日大家还有或用适配iOS
10,那么问题就是应运而生了,如下图:

俺们得到了答案是:

//值为 1
[[[[UIDevice currentDevice] systemVersion] substringToIndex:1] integerValue]
//值为10.000000
[[UIDevice currentDevice] systemVersion].floatValue,
//值为10.0
[[UIDevice currentDevice] systemVersion]

因而说判断系方法极其好或者用后的点滴种植办法,哦~我遗忘说了[[UIDevice currentDevice] systemVersion].floatValue夫法也是未依靠谱的,好像在8.3本输出的值是8.2,记不知道了反而正是不负谱的,所以建议大家之所以[[UIDevice currentDevice] systemVersion]斯点子!

Swift判断如下:

  if #available(iOS 10.0, *) {
            // iOS 10.0
            print("iOS 10.0");
        } else { }

参考文章如下:
iOS 日常工作之常因此宏定义大全

12.Xcode 8 插件不可知就此底问题

世家还提升了Xcode 8,但是于插件依赖的开发者们,一边哭着一边去网上查找解决办法。那么下是解决办法:
于您的 Xcode8
继续下插件

然而看文章最后之说明,我们懂得如果用插件的口舌,可能安全及会出题目、并且付诸审核会被拒,所以建议大家要么不要为此了,解决办法总是有些,比如在Xcode中添加注释的代码块呢是可怜有益于之。

13.iOS 10初始项目被有些文字显示不全问题

我用Xcode 8Xcode 7.3独家测试了下,如下图:

Xcode 8

Xcode 7

创建一个Label然后给它们从适应大小,字体大小都是17说到底输出的宽度是不均等的,我们重新拘留一下,下面的数量就理解干什么升级iOS 10
之后App遭逢有的文字显示不净了:

Xcode 8打印 Xcode 7.3打印
1个文字宽度:17.5 1个文字宽度:17
2个文字宽度:35 2个文字宽度:34
3个文字宽度:52 3个文字宽度:51
4个文字宽度:69.5 4个文字宽度:68
5个文字宽度:87 5个文字宽度:85
6个文字宽度:104 6个文字宽度:102
7个文字宽度:121.5 7个文字宽度:119
8个文字宽度:139 8个文字宽度:136
9个文字宽度:156 9个文字宽度:153
10个文字宽度:173.5 10个文字宽度:170

英文字母会无见面为出这种题材,我还要经测试,后来意识英文字母没有问题,只有汉字有问题。目前只有一个一个改控件解决此问题,暂时没有另外好点子来化解。

14.Xcode 8运Xib awakeFromNib的警戒问题

(本条更新让:2016-09-18)
Xcode 8事先我们下Xib初始化- (void)awakeFromNib {}还是这样写吧从没什么问题,但是当Xcode 8会发如下警告:

若不喜欢这个警示的话,应该明白的丰富[super awakeFromNib];咱们来探视官方证实:

You must call the super implementation of awakeFromNib to give parent
classes the opportunity to perform any additional initialization they
require. Although the default implementation of this method does
nothing, many UIKit classes provide non-empty implementations. You may
call the super implementation at any point during your own
awakeFromNib method.

15.Xcode 8编译过慢的题目

(本条更新受:2016-09-20)
众人数犹体现Xcode 8从未有过前面编译快了,甚至略人慢慢悠悠的辣眼睛。但是自之从未有过感觉异常缓慢,跟之前多,我觉着同电脑当发有联系吧,有的开发者几独月不还开电脑,电脑里运行一堆线程,一积没因此底排泄物。下面是加快Xcode编译的主意,感兴趣的可以去看一下:
加强Xcode编译速度

16.iOS 10 ImagePickerController.cameraViewTransform问题

(本条更新为:2016-09-21)
无数人数反映自定义相机出现了问题,cameraViewTransform匪可知就此了,其实网上有关这个的材料不是多,在此提供参考办法如下:

  • 通过监听AVCaptureSessionDidStartRunningNotification来解决

  //#import <AVFoundation/AVFoundation.h>
  //监听
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cameraNotification:) name:AVCaptureSessionDidStartRunningNotification object:nil];
  //监听方法
  - (void)cameraNotification:(NSNotification *)notification {
    dispatch_async(dispatch_get_main_queue(), ^{
          // 这里实现
          imagePickerController.cameraViewTransform = CGAffineTransformMakeTranslation(50,  50);
      });
  }
  • 使用AVFoundation框架
    看来UIImagePickerController视乎不以适用于iOS 10了。所以说可以选取AVFoundation来解决是题材。
    下面是参照学习:
    UIImagePickerController’s
    cameraViewTransform

本文就吧整治iOS 10 相关资料,也参照部分网上的稿子,还见面陆续更新任何iOS
10 相关资料,以及开发中相见的问题等等。
本文章首发地址:http://www.jianshu.com/p/0cc7aad638d9
iOS 10
苹果官方文档