设计模式

一种或几种被所有程序员广泛认同的,有某些特定功能,或者实现某些特殊作用的编码格式

单例模式

键值编码(KVC)

键值观察(KVO)

观察者模式()

工厂模式(工厂方法)

ps:MVC && MVVM && CVC

一、单例模式

 #import <Foundation/Foundation.h>

 /*
单例模式
1.通常情况下,一个工程只有一个单例类。
2.我们将一个类选中,将它作为单例类。
3.在整个工程中这个类所创建的对象是唯一并且不能被释放 作用:界面传值-在整个工程任意位置对单例对象的属性进行赋值
也可以在整个工程的任意位置对单例对象的属性进行访问
*/
@interface Globle : NSObject @property (strong, nonatomic) NSString *userId; // 单例方法
// 作用:获取唯一单例对象
+ (Globle*) shareGloble;//getGloble @end #import "Globle.h" // 创建一个单例对象,用静态修饰符将这个对象的生命周期延长至整个工程
static Globle *globle = nil; @implementation Globle +(Globle *)shareGloble
{
// 第一次执行单例方法,将单例对象初始化
if (globle == nil) {
globle = [[Globle alloc] init];
globle.userId = @"";
}
// 之后的每次调用,都会直接返回上面的唯一单例对象
return globle;
}
@end #import <Foundation/Foundation.h>
#import "Globle.h" @interface People : NSObject +(void) showUserId; @end #import "People.h" @implementation People +(void)showUserId
{
NSLog(@"userId:%@",[Globle shareGloble].userId);
}
@end #import <Foundation/Foundation.h>
#import "Globle.h"
#import "People.h" int main(int argc, const char * argv[]) {
@autoreleasepool { [Globle shareGloble].userId = @"";
[People showUserId]; }
return ;
}

二、KVC

 #import <Foundation/Foundation.h>

 /*
KVC key-value-coding 作用:能够无视OC中关于私有的设定,直接通过底层赋值方式对属性赋值(和获取); */
@interface KVCClass : NSObject -(void) showProperty; @end #import "KVCClass.h"
#import "Student.h" @interface KVCClass () @property (strong, nonatomic) NSString *kvcProperty;
@property (strong, nonatomic) Student *tempStu; @end @implementation KVCClass - (instancetype)init
{
self = [super init];
if (self) {
self.tempStu =[[Student alloc] init];
}
return self;
} -(void)showProperty
{
NSLog(@"property:%@",self.kvcProperty);
NSLog(@"property:%@",self.tempStu.name); }
@end #import <Foundation/Foundation.h> @interface Student : NSObject @property (strong, nonatomic) NSString *name; @end #import "Student.h" @implementation Student @end #import <Foundation/Foundation.h> #import "KVCClass.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
KVCClass *kvc = [[KVCClass alloc] init]; //表示 在KVC对象中查找名字为[kvcProperty] 的属性,并对这个属性赋值为@“bowen”
// 设置
[kvc setValue:@"bowen" forKey:@"kvcProperty"]; [kvc setValue:@"bowen1" forKeyPath:@"tempStu.name"]; [kvc showProperty];
// 取值

NSLog(@"%@",[kvc valueForKey:@"kvcProperty"]);

         NSLog(@"%@",[kvc valueForKeyPath:@"tempStu.name"]);
}
return ;
}

OC中的KVC操作就和Java中使用反射机制去访问类的private权限的变量,很暴力的,这样做就会破坏类的封装性,本来类中的的private权限就是不希望外界去访问的,但是我们这样去操作,就会反其道而行,但是我们有时候真的需要去这样做,哎。所以说有些事不是都是顺其自然的,而是需要的时候自然就诞生了。

下面就来看一下这种技术的使用:

Dog.h

  1. //
  2. //  Dog.h
  3. //  42_KVC
  4. //
  5. //  Created by jiangwei on 14-10-14.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. @interface Dog : NSObject
  10. @end

Dog.m

  1. //
  2. //  Dog.m
  3. //  42_KVC
  4. //
  5. //  Created by jiangwei on 14-10-14.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Dog.h"
  9. @implementation Dog
  10. @end

定义了Dog这个类,但是什么都没有,他只是一个中间类,没什么作用,在这个demo中。

Person.h

  1. //
  2. //  Person.h
  3. //  42_KVC
  4. //
  5. //  Created by jiangwei on 14-10-14.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "Dog.h"
  10. @interface Person : NSObject{
  11. @private
  12. NSString *_name;
  13. NSDog *_dog;
  14. NSInteger *age;
  15. }
  16. @end

Person.m

  1. //
  2. //  Person.m
  3. //  42_KVC
  4. //
  5. //  Created by jiangwei on 14-10-14.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Person.h"
  9. @implementation Person
  10. - (NSString *)description{
  11. NSLog(@"%@",_name);
  12. return _name;
  13. }
  14. @end

Person类中我们定义了两个属性,但是这两个属性对外是不可访问的,而且也没有对应的get/set方法。我们也实现了description方法,用于打印结果

看一下测试代码

main.m

  1. //
  2. //  main.m
  3. //  42_KVC
  4. //
  5. //  Created by jiangwei on 14-10-14.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "Person.h"
  10. #import "Dog.h"
  11. //KVC:很暴力,及时一个类的属性是私有的,而且也没有get/set方法,同样可以读写
  12. //相当于Java中的反射,破坏类的封装性
  13. int main(int argc, const charchar * argv[]) {
  14. @autoreleasepool {
  15. Person *p = [[Person alloc] init];
  16. //设置值
  17. //这里setValue方法:第一个参数是value,第二个参数是key(就是类的属性名称)
  18. [p setValue:@"jiangwei" forKey:@"name"];
  19. Dog *dog = [[Dog alloc] init];
  20. [p setValue:dog forKey:@"dog"];
  21. //KVC设置值时,如果属性有set方法,则优先调用set方法,如果没有则直接设置上去,get方法类似
  22. //读取值
  23. NSString *name = [p valueForKey:@"name"];
  24. //设置基本数据类型
  25. //这里需要将基本类型转化成NSNumber
  26. //在设置值的时候,会有自动解包的过程,NSNumber会解包赋值给age
  27. [p setValue:@22 forKey:@"age"];
  28. NSLog(@"%@",p);
  29. return 0;
  30. }
  31. return 0;
  32. }

这里我们生成一个Person对象,然后开始使用KVC技术了:

1、设置属性值

  1. //设置值
  2. //这里setValue方法:第一个参数是value,第二个参数是key(就是类的属性名称)
  3. [p setValue:@"jiangwei" forKey:@"name"];
  4. Dog *dog = [[Dog alloc] init];
  5. [p setValue:dog forKey:@"dog"];

使用setValue方法,就可以进行对属性进行设置值操作了,同时需要传递这个属性的名称,这个和Java中使用反射机制真的很像。

注:KVC设置值时,如果属性有set方法,则优先调用set方法,如果没有则直接设置上去,get方法一样

  1. //设置基本数据类型
  2. //这里需要将基本类型转化成NSNumber
  3. //在设置值的时候,会有自动解包的过程,NSNumber会解包赋值给age
  4. [p setValue:@22 forKey:@"age"];

还有一个需要注意的地方:当我们在设置基本类型的时候,需要将其转化成NSNumber类型的。

2、取属性的值

  1. //读取值
  2. NSString *name = [p valueForKey:@"name"];

取值就简单了

下面再来看一下KVC中强大的功能:键值路径

键值路径是对于一个类中有数组对象的属性进行便捷操作。

看个场景:

一个作者有多本书

Author.h

  1. //
  2. //  Author.h
  3. //  43_KeyValuePath
  4. //
  5. //  Created by jiangwei on 14-10-15.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. @interface Author : NSObject{
  10. NSString *_name;
  11. //作者出版的书,一个作者对应多个书籍对象
  12. NSArray *_issueBook;
  13. }
  14. @end

作者类中定义了名字和一个书籍数组

Author.m

  1. //
  2. //  Author.m
  3. //  43_KeyValuePath
  4. //
  5. //  Created by jiangwei on 14-10-15.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Author.h"
  9. @implementation Author
  10. @end

Book.h

  1. //
  2. //  Book.h
  3. //  43_KeyValuePath
  4. //
  5. //  Created by jiangwei on 14-10-15.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "Author.h"
  10. @interface Book : NSObject{
  11. Author *_author;
  12. }
  13. @property NSString *name;
  14. @property floatfloat *price;
  15. @end

定义了一个作者属性,书的名字,价格

Book.m

  1. //
  2. //  Book.m
  3. //  43_KeyValuePath
  4. //
  5. //  Created by jiangwei on 14-10-15.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import "Book.h"
  9. @implementation Book
  10. @end

看一下测试代码

main.m

  1. //
  2. //  main.m
  3. //  43_KeyValuePath
  4. //
  5. //  Created by jiangwei on 14-10-15.
  6. //  Copyright (c) 2014年 jiangwei. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "Book.h"
  10. #import "Author.h"
  11. int main(int argc, const charchar * argv[]) {
  12. @autoreleasepool {
  13. //------------------KVC键值路径
  14. /*
  15. Book *book = [[Book alloc] init];
  16. Author *author = [[Author alloc] init];
  17. //设置作者
  18. [book setValue:author forKey:@"author"];
  19. //设置作者的名字
  20. //路径为:author.name,中间用点号进行连接
  21. [book setValue:@"jiangwei" forKeyPath:@"author.name"];
  22. NSString *name = [author valueForKey:@"name"];
  23. NSLog(@"name is %@",name);
  24. */
  25. //--------------------KVC的运算
  26. Author *author = [[Author alloc] init];
  27. [author setValue:@"莫言" forKeyPath:@"name"];
  28. Book *book1 = [[Book alloc] init];
  29. book1.name = @"红高粱";
  30. book1.price = 9;
  31. Book *book2 = [[Book alloc] init];
  32. book2.name = @"蛙";
  33. book2.price = 10;
  34. NSArray *array = [NSArray arrayWithObjects:book1,book2, nil nil];
  35. [author setValue:array forKeyPath:@"issueBook"];
  36. //基本数据类型会自动被包装成NSNumber,装到数组中
  37. //得到所有书籍的价格
  38. NSArray *priceArray = [author valueForKeyPath:@"issueBook.price"];
  39. NSLog(@"%@",priceArray);
  40. //获取数组的大小
  41. NSNumber *count = [author valueForKeyPath:@"issueBook.@count"];
  42. NSLog(@"count=%@",count);
  43. //获取书籍价格的总和
  44. NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"];
  45. NSLog(@"%@",sum);
  46. //获取书籍的平均值
  47. NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"];
  48. NSLog(@"%@",avg);
  49. //获取书籍的价格最大值和最小值
  50. NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"];
  51. NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"];
  52. }
  53. return 0;
  54. }

1、首先通过前面说到的KVC设置作者的书籍数组

  1. //--------------------KVC的运算
  2. Author *author = [[Author alloc] init];
  3. [author setValue:@"莫言" forKeyPath:@"name"];
  4. Book *book1 = [[Book alloc] init];
  5. book1.name = @"红高粱";
  6. book1.price = 9;
  7. Book *book2 = [[Book alloc] init];
  8. book2.name = @"蛙";
  9. book2.price = 10;
  10. NSArray *array = [NSArray arrayWithObjects:book1,book2, nil nil];
  11. [author setValue:array forKeyPath:@"issueBook"];

添加了两本书籍

2、下面就开始用到KVC中键值路径了

1)获取作者类中书籍数组中所有书籍的价格

  1. //基本数据类型会自动被包装成NSNumber,装到数组中
  2. //得到所有书籍的价格
  3. NSArray *priceArray = [author valueForKeyPath:@"issueBook.price"];
  4. NSLog(@"%@",priceArray);

看到了:@"issueBook.price" 这就是键值路径的使用,issueBook是作者类中的书籍数组属性名,price是书籍类的属性,中间用点号进行连接,这样我们就可以获取到了所有书籍的价格了,如果在Java中,我们需要用一个循环操作。但是OC中多么方便。

2)获取作者类中书籍数组的大小

  1. //获取数组的大小
  2. NSNumber *count = [author valueForKeyPath:@"issueBook.@count"];
  3. NSLog(@"count=%@",count);

使用 @"issueBook.@count" 键值路径获取书籍数组的大小,issueBook是作者类中的书籍数组属性名,@count是特定一个写法,可以把它想象成一个方法,中间任然用点号进行连接

3)获取作者类中书籍数组的价格总和

  1. //获取书籍价格的总和
  2. NSNumber *sum = [author valueForKeyPath:@"issueBook.@sum.price"];
  3. NSLog(@"%@",sum);

使用 @"issueBook.@sum.price" 键值路径获取书籍数组中的价格总和,issueBook是作者类中的书籍数组属性名,@sum是特性写法,可以把它想象成一个方法,price是书籍的价格属性名,可以把它看成是@sum的一个参数,中间用点号进行连接

如果在java中,这个需要用一个循环来计算总和,OC中很方便的

4)获取作者类中书籍数组的价格平均值、最小值、最大值

  1. //获取书籍的平均值
  2. NSNumber *avg = [author valueForKeyPath:@"issueBook.@avg.price"];
  3. NSLog(@"%@",avg);
  4. //获取书籍的价格最大值和最小值
  5. NSNumber *max = [author valueForKeyPath:@"issueBook.@max.price"];
  6. NSNumber *min = [author valueForKeyPath:@"issueBook.@min.price"];

操作和上面类似,这里就不解释了

我们看到上面返回来的数据都是NSNumber类型的

三、观察者模式

 #import <Foundation/Foundation.h>

 /*
观察者模式(通知模式)NSNotification
观察者中心 NSNotificationCenter 注册观察者必需在[发出通知]之前 */ @interface House : NSObject -(void) burn; @end #import "House.h" @implementation House -(void)burn
{
NSLog(@"房子着火了");
// 发出通知
[[NSNotificationCenter defaultCenter] postNotificationName:@"PlanB" object:nil];
}
@end #import <Foundation/Foundation.h> @interface Child : NSObject -(void) loudSay; -(void) toBeAGuanChazhe; @end #import "Child.h" @implementation Child -(void) loudSay
{
NSLog(@"报告:房子着火了");
} -(void)toBeAGuanChazhe
{
// 创建观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loudSay) name:@"PlanB" object:nil];
}
@end #import <Foundation/Foundation.h> #import "House.h"
#import "Child.h" int main(int argc, const char * argv[]) {
@autoreleasepool { House *myhouse = [[House alloc] init]; Child *mychild = [[Child alloc] init]; // 让mychild 成为观察者
[mychild toBeAGuanChazhe]; // 让房子着火,发出PlanB现象
[myhouse burn];
}
return ;
}

四、KVO

 #import <Foundation/Foundation.h>
#import "JieCao.h" /*
KVO key-value-observer(键值观察) 作用:能够在被观察的某个属性发生变化的时候,自动执行某些方法 当被观察的某个属性发生变化的时候,这个方法被自动回调 -(void) observer... pss:当键值观察的观察者被使用完毕之后必须注销
psss:键值观察是在[某个类中]给[某个属性] 注册观察者,当这个属性的值发生变化后作出响应模式 */ @interface Bowen : NSObject @property (strong,nonatomic) JieCao *my_jieCao; @end #import "Bowen.h" @implementation Bowen -(void) setMy_jieCao:(JieCao *)my_jieCao
{
_my_jieCao = my_jieCao; //注册观察者,观察_my_jieCao属性的值的变化
[_my_jieCao addObserver:self forKeyPath:@"jieCaoValue" options:NSKeyValueObservingOptionNew context:nil]; }
// 不管在一个类当中注册一个多少KVO的观察者,本方法只能写一个
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"jieCaoValue"]) { if ([[change objectForKey:@"new"] integerValue]<) {
NSLog(@"我要吐了,受不了老师了");
}
// NSLog(@"keyPath:%@",keyPath);
// NSLog(@"Object:%@",keyPath);
// NSLog(@"change:%@",[change objectForKey:@"new"]); }
}
- (void)dealloc
{
[_my_jieCao removeObserver:self forKeyPath:@"jieCaoValue"];
} @end #import <Foundation/Foundation.h> @interface JieCao : NSObject @property (assign, nonatomic) NSInteger jieCaoValue; @end #import "JieCao.h" @implementation JieCao @end #import <Foundation/Foundation.h> #import "Bowen.h"
#import "JieCao.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
// 创建被观察属性
JieCao *jieCao = [[JieCao alloc] init];
jieCao.jieCaoValue = ;
// 创建观察对象
Bowen *bowen = [[Bowen alloc] init];
// 让观察对象开始观察[被观察属性]
bowen.my_jieCao = jieCao;
// 让被观察属性发生变化
bowen.my_jieCao.jieCaoValue = ;
}
return ;
}

五、工厂模式

 #import <Foundation/Foundation.h>
#import "Fruit.h" /* 工厂模式:(工厂方法) 个人理解:实际上就是用来快速大批量生产对象的 优点:能够将原本在本类初始化的对象,延时到子类中去初始化。实现了一个开放封闭原则。 */ @interface FruitFactory : NSObject // 通过外部输入的名字,创建[名字对应的类] 的对象
+ (Fruit *)createFruitByName:(NSString *) name; @end #import "FruitFactory.h" @implementation FruitFactory +(Fruit *)createFruitByName:(NSString *)name
{
//需要知道名字对应的类
Class class = NSClassFromString(name);
// 创建想要的类对象
Fruit *fruit = [[class alloc] init];
// 返回新建的[想要的类]的对象
return fruit;
}
@end #import <Foundation/Foundation.h> @interface Fruit : NSObject -(void) show; @end #import "Fruit.h" @implementation Fruit -(void)show
{
NSLog(@"I'm fruit");
}
@end #import "Fruit.h" @interface Apple : Fruit @end #import "Apple.h" @implementation Apple -(void)show
{
NSLog(@"I'm apple");
} #import "Fruit.h" @interface Banana : Fruit @end #import "Banana.h" @implementation Banana -(void)show
{
NSLog(@"I'm banana");
} @end #import "Fruit.h" @interface Pear : Fruit @end #import "Pear.h" @implementation Pear -(void)show
{
NSLog(@"I'm pear");
} @end #import <Foundation/Foundation.h>
#import "FruitFactory.h" int main(int argc, const char * argv[]) {
@autoreleasepool {
Fruit *fruit = [FruitFactory createFruitByName:@"Apple"];
[fruit show];
Fruit *fruit1 = [FruitFactory createFruitByName:@"Banana"];
[fruit1 show];
Fruit *fruit2 = [FruitFactory createFruitByName:@"Pear"];
[fruit2 show];
}
return ;
}

OC 设计模式的更多相关文章

  1. OC—设计模式-通知的使用

    通知 通知(广播) 可以一对多的发送通知(一个发送者 多个观察者) 特别注意:在发送者 发送通知的时候,必须有观察者 发送者,就是注册一个通知中心,以他为中心,发送消息 通过通知的名字,来判断是哪个通 ...

  2. OC 设计模式——单例模式

    单例模式的作用:可以保证在程序运行过程,一个类只有一个实例,而且这个实例易于供外界访问.永远只分配一次内存给这个类.由于在调用alloc方法的时候,都会调用allocWithZone,所以要重写这个方 ...

  3. [转载]iOS面试题总

    转载自:http://blog.sina.com.cn/s/blog_67eb608b0101r6xb.html (2014-06-13 20:23:33) 转载▼ 标签: 转载   crash 原文 ...

  4. iOS 面试题 2

    1.         描述应用程序的启动顺序. 1.程序入口main函数创建UIApplication实例和UIApplication代理实例 2.在UIApplication代理实例中重写启动方法, ...

  5. iOS 面试题整理(带答案)二

    第一篇面试题整理: http://www.cocoachina.com/bbs/read.php?tid-459620.html 本篇面试题同样:如答案有问题,欢迎指正! 1.回答person的ret ...

  6. iOS 重构AppDelegate

    一.Massive AppDelegate AppDelegate 是应用程序的根对象,它连接应用程序和系统,确保应用程序与系统以及其他应用程序正确的交互,通常被认为是每个 iOS 项目的核心. 随着 ...

  7. 设计模式之观察者模式(关于OC中的KVO\KVC\NSNotification)

    学习了这么久的设计模式方面的知识,最大的感触就是,设计模式不能脱离语言特性.近段时间所看的两本书籍,<大话设计模式>里面的代码是C#写的,有一些设计模式实现起来也是采用了C#的语言特性(C ...

  8. OC中的单例设计模式及单例的宏抽取

    // 在一个对象需要重复使用,并且很频繁时,可以对对象使用单例设计模式 // 单例的设计其实就是多alloc内部的allocWithZone下手,重写该方法 #pragma Person.h文件 #i ...

  9. 【OC加强】辛格尔顿和[NSFileManager defaultMagager]以及其他设计模式

    我们在工作中使用文件NSFileManager上课时间,创建发现1对象,此2同样的对象地址: NSFileManager *file1=[NSFileManager defaultManager]; ...

随机推荐

  1. Python Web学习笔记之进程与线程

    要了解二者的区别与联系,首先得对进程与线程有一个宏观上的了解. 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位.每一个进程都有一个自己的地址空 ...

  2. 深入JAVA注解之方法注解

    以获取数据库连接为例,建立maven项目 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" ...

  3. 20145105 《Java程序设计》实验三总结

    实验三 一.       实验内容 结对修改实验一代码,重点学习重构 二.       实验步骤 下载结伴同学的实验一代码 初始代码 进行整数.小数和负数的多组数据测试,发现一个运行错误的例子 分析后 ...

  4. CF873B Balanced Substring

    1到n内0,1个数相同的个数的最长字串 \(i>=j\) \[1的个数=0的个数\] \[sum[i]-sum[j-1]=i-(j-1) - (sum[i]-sum[j-1])\] 这里把\(( ...

  5. java自学入门心得体会 0.1

    之前记录了java的简介和基本语法 这里记载下对象和类 不太懂的我理解java对象和类的概念很模糊,因为有了 Abstract修饰符 让对象与类更加的扑朔迷离 - - 所以,就像很开放的语言,创建对象 ...

  6. Unity3D学习笔记(二十):Rect、Canvas、Toggle、Slider、ScrollBar

      Rect Transform(锚点):图片中心的四个点,界面以雪花形式显示 当四个点在一起的时候组成锚点,当四个点分开的时候组成锚框(合则锚点,分则锚框) Anchors: ----Min x:控 ...

  7. C#学习笔记(一):C#简介

    计算机语言计算机语言是指用于人与计算机之间通讯的语言机器码——汇编语言——高级语言(面向过程(线性).面向对象(类).面向组件(Unity)) 一.计算机语言发展趋势1.简单:代码生成逻辑2.面向人类 ...

  8. flink架构介绍

    前言 flink作为基于流的大数据计算引擎,可以说在大数据领域的红人,下面对flink-1.7的架构进行逻辑上的分析并和spark做了一些关键点的对比. 架构 如图1,flink架构分为3个部分,cl ...

  9. Network Simulator for P4(NSP4) src内容介绍

    Structure What's NSP4? src source code introduction What's NSP4? NSP4是一个用于P4的网络仿真工具,旨在简化P4的环境部署和运行,将 ...

  10. codeforces 351 div2 C. Bear and Colors 暴力

    C. Bear and Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...