OC中幾種常用的設(shè)計(jì)模式以及工廠模式(Java版)

一你弦、OC中幾種常用的設(shè)計(jì)模式

1.單例模式(Singleton)

在iOS開發(fā)我們經(jīng)常碰到只需要某類一個(gè)實(shí)例的情況,如:

● UIApplication類提供了 +sharedAPplication方法創(chuàng)建和獲取UIApplication單例

● NSBundle類提供了 +mainBunle方法獲取NSBundle單例

● NSFileManager類提供了 +defaultManager方法創(chuàng)建和獲得NSFileManager單例。(PS:有些時(shí)候我們得放棄使用單例模式尸昧,使用-init方法去實(shí)現(xiàn)一個(gè)新的實(shí)例烹俗,比如使用委托時(shí))

● NSNotificationCenter提供了 +defaultCenter方法創(chuàng)建和獲取NSNotificationCenter單例(PS:該類還遵循了另一個(gè)重要的設(shè)計(jì)模式:觀察者模式)

● NSUserDefaults類提供了 +defaultUserDefaults方法去創(chuàng)建和獲取NSUserDefaults單例

如何實(shí)現(xiàn)單例模式

首先給大家介紹一下GCD技術(shù)萍程,是蘋果針對于多核CPU的多任務(wù)解決方案茫负。是一組基于C語言開發(fā)的API。GCD提供了一個(gè)dispatch_once函數(shù)置吓,這個(gè)函數(shù)的作用就是保證block里的語句在整個(gè)應(yīng)用的生命周期里只執(zhí)行一次缔赠。

實(shí)現(xiàn)代碼

#import "JasonDemo.h"

@implementation JasonDemo


+ (instancetype)sharedInstance {
    static JasonDemo *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[JasonDemo alloc] init];
    });
    return sharedInstance;
}

@end

上述代碼中有5小步嗤堰,解釋如下:

  1. 聲明一個(gè)可以新建和獲取單個(gè)實(shí)例對象的方法

  2. 聲明一個(gè)static類型的類變量

  3. 聲明一個(gè)只執(zhí)行一次的任務(wù)

  4. 調(diào)用dispatch_once執(zhí)行該任務(wù)指定的代碼塊踢匣,在該代碼塊中實(shí)例化上文聲明的類變量

  5. 返回在整個(gè)應(yīng)用的生命周期中只會被實(shí)例化一次的變量

單例模式作用

  • 由于單例模式在內(nèi)存中只有一個(gè)實(shí)例,減少了內(nèi)存開支后专,特別是一個(gè)對象需要頻繁地創(chuàng)建输莺、銷毀時(shí)嫂用,而且創(chuàng)建或銷毀時(shí)性能又無法優(yōu)化,單例模式的優(yōu)勢就非常明顯甘畅。

  • 由于單例模式只生成一個(gè)實(shí)例,所以減少了系統(tǒng)的性能開銷蓄氧,當(dāng)一個(gè)對象的產(chǎn)生需要比較多的資源時(shí),如讀取配置缴淋、產(chǎn)生其他依賴對象時(shí),則可以通過在應(yīng)用啟動(dòng)時(shí)直接產(chǎn)生一個(gè)單例對象露氮,然后用永久駐留內(nèi)存的方式來解決(在Java EE中采用單例模式時(shí)需要注意JVM垃圾回收機(jī)制)畔规。

  • 單例模式可以避免對資源的多重占用恨统,例如一個(gè)寫文件動(dòng)作,由于只有一個(gè)實(shí)例存在內(nèi)存中莫绣,避免對同一個(gè)資源文件的同時(shí)寫操作对室。

  • 單例模式可以在系統(tǒng)設(shè)置全局的訪問點(diǎn)咖祭,優(yōu)化和共享資源訪問么翰,例如可以設(shè)計(jì)一個(gè)單例類,負(fù)責(zé)所有數(shù)據(jù)表的映射處理慧瘤。

舉個(gè)栗子

跳轉(zhuǎn)使用單例之前

跳轉(zhuǎn)管理基類

#import <Foundation/Foundation.h>

@class CHBaseController;

@interface CCInteractor : NSObject
{
}

@property (nonatomic, weak)   CHBaseController*       baseController;

@end

具體業(yè)務(wù)跳轉(zhuǎn)子類

@interface CHContactsInteractor : CCInteractor

- (void)goOrganization;

- (void)goMyDepartmentWithDeptID:(NSString *)deptID andDeptName:(NSString *)deptName;

@end

使用

@property (nonatomic, strong) CHContactsInteractor *contactsInteractor;

self.contactsInteractor = [CHContactsInteractor new];

[self.contactsInteractor goOrganization];

使用單例優(yōu)化以后

跳轉(zhuǎn)管理基類

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface ATModuleInteractor : NSObject

+ (instancetype)sharedInstance;

// 普通push
- (void)pushToVC:(UIViewController *)VC;

// 強(qiáng)制跳轉(zhuǎn)rootView再push
- (void)PushToChatVC:(UIViewController *)VC;
@end


具體業(yè)務(wù)跳轉(zhuǎn)管理分類

#import "ATModuleInteractor.h"

@interface ATModuleInteractor (CoordinationInteractor)

// 任務(wù)列表
- (void)goTaskList;
@end

使用

    [[ATModuleInteractor sharedInstance] goTaskList];

2.觀察者模式

概念:操作對象向被觀察者對象投送消息锅减,使得被觀察者的狀態(tài)得以改變怔匣,在此之前已經(jīng)有觀察者向被觀察對象注冊,訂閱它的廣播金闽,現(xiàn)在被觀察對象將自己狀態(tài)發(fā)生改變的消息廣播出來代芜,觀察者接收到消息各自做出應(yīng)變浓利。

蘋果的Cocoa Touch框架中使用了觀察者模式的有:通知機(jī)制和KVO

2.1 通知(notification)機(jī)制

在通知機(jī)制中對某個(gè)通知感興趣的所有對象都可以成為接受者。首先嫡秕,這些對象需要向通知中心(NSNotificationCenter)發(fā)出addObserver:selector:name:object:消息進(jìn)行注冊昆咽,在投送對象投送通知送給通知中心時(shí)牙甫,通知中心就會把通知廣播給注冊過的接受者。所有的接受者不知道通知是誰投送的汇在,不去關(guān)心它的細(xì)節(jié)糕殉。投送對象和接受者是一對多的關(guān)系殖告。接受者如果對通知不再關(guān)注,會給通知中心發(fā)送removeObserver:name:Object:消息解除注冊羡洁,以后不再接受通知爽丹。

代碼嘗試

1.進(jìn)入后臺時(shí)粤蝎,發(fā)出通知

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[NSNotificationCenter defaultCenter]postNotificationName:@"APPTerminate" object:self];
}
#import "ViewController.h"
 
@interface ViewController ()
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    //注意此處的selector有參數(shù),要加冒號
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(doSomething:) name:@"APPTerminate" object:nil];
    // Do any additional setup after loading the view, typically from a nib.
}
 
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    [[NSNotificationCenter defaultCenter]removeObserver:self];
    // Dispose of any resources that can be recreated.
}
 
#pragma mark -處理通知
-(void)doSomething:(NSNotification*)notification{
    NSLog(@"收到進(jìn)入后臺通知");
}
 
@end

在APP退到后臺時(shí)秸应,發(fā)出廣播软啼,而viewController因?yàn)闀r(shí)觀察者,收到廣播锣披,執(zhí)行doSomething方法雹仿,打印出收到廣播的文字闪唆。

2.2 KVO(Key-Value-Observing)機(jī)制

該機(jī)制下觀察者的注冊是在被觀察者的內(nèi)部進(jìn)行的钓葫,不同于通知機(jī)制(由觀察者自己注冊),需要被觀察者和觀察者同時(shí)實(shí)現(xiàn)一個(gè)協(xié)議:NSKeyValueObserving帆调,被觀察者通過addObserver:forKeypath:options:context方法注冊觀察者番刊,以及要被觀察的屬性影锈。

實(shí)現(xiàn)代碼

被觀察類(由于繼承自NSObject,而NSObject已實(shí)現(xiàn)了NSKeyValueObserving協(xié)議,所以不需要做聲明)

#import <Foundation/Foundation.h>

@interface JWWatchModel : NSObject
@property (nonatomic, copy) NSString *JWName;
@property (nonatomic, copy) NSString *JWAge;
@end

觀察類

- (void)viewDidLoad {
    [super viewDidLoad];
    self.JWModel = [JWWatchModel new];
    
    [self.JWModel addObserver:self forKeyPath:@"JWName" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:@"你考了幾分"];
    UIBarButtonItem *changeBtn = [[UIBarButtonItem alloc] initWithTitle:@"戳我啊" style:UIBarButtonItemStylePlain target:self action:@selector(changeClick)];
    [self.navigationItem setRightBarButtonItem:changeBtn];
    
    // Do any additional setup after loading the view.
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"JWName"]) {
        UIAlertController *alterVC = [UIAlertController alertControllerWithTitle:(__bridge NSString *)context message:[self dictionaryToJson:change] preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *action = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:nil];
        [alterVC addAction:action];
        [self presentViewController:alterVC animated:YES completion:nil];
        NSLog(@"%@",change);
    }
}

3.委托代理模式

委托模式就像是java中的接口,類可以實(shí)現(xiàn)或不實(shí)現(xiàn)協(xié)議(接口)中的方法辆床。通過此種方式,達(dá)到最大的解耦目的轿秧,方便項(xiàng)目的擴(kuò)展菇篡。不過你需要設(shè)置應(yīng)用的委托對象一喘,以確定協(xié)議中的方法為誰服務(wù)。

拿最常用的UITableViewDelegate UITableViewDataSource來舉例:

實(shí)現(xiàn)一個(gè)頁面有一個(gè)UItableView铝侵,UItableView的每一欄(cell)的數(shù)據(jù)由我們指定,那么我們該如何做呢狐赡?蘋果也自然想到了這一點(diǎn)颖侄,于是定義了一個(gè)接口享郊,這個(gè)接口有許多的方法,只需要我們把要服務(wù)的對象傳進(jìn)去展蒂,就可以使用這些方法了苔咪,這個(gè)接口就是委托和協(xié)議。而UITableViewDelegate 和 UITableViewDataSource 就是專為UITableView而寫的委托和協(xié)議箕般。用法如下:

#pragma mark - UITableView Delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.serviceDetail.payWayList.count;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *CoustomerTableIdentifier = @"RecipeTableCellTableViewCell";
 
    RecipeTableCellTableViewCell *cell =(RecipeTableCellTableViewCell *) [tableView dequeueReusableCellWithIdentifier:CoustomerTableIdentifier];
 
    if (cell == nil) {
       cell = [[RecipeTableCellTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CoustomerTableIdentifier];
    }
 
    recipe = [recipes objectAtIndex:indexPath.row];
 
    cell.nameLabel.text =  recipe.name;
    cell.prepTimeLabel.text= recipe.prepTime;
    cell.thumbnailImageView.image = [UIImage imageNamed:recipe.image];
 
    return cell;}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 0.0001;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    return 0.0001;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ServicePayWay *payway = self.serviceDetail.payWayList[indexPath.row];
    if ([self.selectedPayway.payWayCode isEqualToString:payway.payWayCode]) {
        return;
    }
    self.selectedPayway = payway;
    [self.tableView reloadData];
}

如上所示的方法全部來自于委托和協(xié)議丝里。利用委托和協(xié)議杯聚,你可以把主要精力放到邏輯業(yè)務(wù)上营密,將數(shù)據(jù)綁定和事件處理交給委托和協(xié)議去完成评汰。

二、工廠模式

女媧造人的故事

東漢《風(fēng)俗通》記錄了一則神話故事:“開天辟地主儡,未有人民惨缆,女媧搏黃土做人”丰捷,講述的內(nèi)容就是大家非常熟悉的女媧造人的故事病往。開天辟地之初骄瓣,大地上并沒有生物,只有蒼茫大地畔勤,純粹而潔凈的自然環(huán)境庆揪,寂靜而又寂寞妨托,于是女媧決定創(chuàng)造一個(gè)新物種(即人類)來增加世界的繁榮,怎么制造呢仔掸?

別忘了女媧是神仙医清,沒有辦不到的事情卖氨,造人的過程是這樣的:首先,女媧采集黃土捏成人的形狀柏腻,然后放到八卦爐中燒制五嫂,最后放置到大地上生長肯尺,工藝過程是沒有錯(cuò)的,但是意外隨時(shí)都會發(fā)生:

第一次烤泥人槐臀,感覺應(yīng)該熟了氓仲,往大地上一放得糜,哇朝抖,沒烤熟槽棍!于是一個(gè)白人誕生了L俊(這也是缺乏經(jīng)驗(yàn)的最好證明)

第二次烤泥人,上一次沒烤熟豌拙,這次多烤一會兒题暖,放到世間一看,嘿唯绍,熟過頭了枝誊,于是黑人誕生了!

第三次烤泥人绝骚,一邊燒制一邊察看压汪,直到表皮微黃古瓤,嘿,真正好穿香,于是黃色人種出現(xiàn)了叽奥!

這個(gè)造人過程是比較有意思的,是不是可以通過軟件開發(fā)來實(shí)現(xiàn)這個(gè)過程呢魔市?古人云:“三人行,必有我?guī)熝伞贝拢诿嫦驅(qū)ο蟮乃季S中将宪,萬物皆對象,是對象我們就可以通過軟件設(shè)計(jì)來實(shí)現(xiàn)印蔗。首先對造人過程進(jìn)行分析丑勤,該過程涉及三個(gè)對象:女媧、八卦爐耙厚、三種不同膚色的人岔霸。女媧可以使用場景類Client來表示,八卦爐類似于一個(gè)工廠型宝,負(fù)責(zé)制造生產(chǎn)產(chǎn)品(即人類)诡曙,三種不同膚色的人略水,他們都是同一個(gè)接口下的不同實(shí)現(xiàn)類劝萤,都是人嘛,只是膚色跨释、語言不同厌处,對于八卦爐來說都是它生產(chǎn)出的產(chǎn)品。分析完畢缆娃,我們就可以畫出如圖8-1所示的類圖。

d7260e63844769eae109ed60.jpeg

圖8-1

類圖比較簡單暖侨,AbstractHumanFactory是一個(gè)抽象類字逗,定義了一個(gè)八卦爐具有的整體功能宅广,HumanFactory為實(shí)現(xiàn)類,完成具體的任務(wù)——?jiǎng)?chuàng)建人類挖息;Human接口是人類的總稱兽肤,其三個(gè)實(shí)現(xiàn)類分別為三類人種;NvWa類是一個(gè)場景類电禀,負(fù)責(zé)模擬這個(gè)場景笤休,執(zhí)行相關(guān)的任務(wù)。

我們定義的每個(gè)人種都有兩個(gè)方法:getColor(獲得人的皮膚顏色)和talk(交談)政基,其源代碼如代碼清單8-1所示沮明。

代碼清單8-1 人類總稱

public interface Human{
//每個(gè)人種的皮膚都有相應(yīng)的顏色
public void getColor()窍奋;
//人類會說話
public void talk();
}

接口Human是對人類的總稱江场,每個(gè)人種都至少具有兩個(gè)方法窖逗,黑色人種、黃色人種佑附、白色人種的代碼分別如代碼清單8-2、代碼清單8-3啄骇、代碼清單8-4所示瘟斜。

代碼清單8-2 黑色人種

public class BlackHuman implements Human{
public void getColor(){
System.out.println("黑色人種的皮膚顏色是黑色的!")虽惭;
}
public void talk(){
System.out.println("黑人會說話蛇尚,一般人聽不懂。")匆笤;
}
}

代碼清單8-3黃色人種

public class YellowHuman implements Human{
public void getColor(){
System.out.println("黃色人種的皮膚顏色是黃色的炮捧!")惦银;
}
public void talk(){
System.out.println("黃色人種會說話,一般說的都是雙字節(jié)书蚪。")迅栅;
}
}

代碼清單8-4 白色人種

public class WhiteHuman implements Human{
public void getColor(){
System.out.println("白色人種的皮膚顏色是白色的!")箩艺;
}
public void talk(){
System.out.println("白色人種會說話,一般都是但是單字節(jié)榨惰。");
}
}

所有的人種定義完畢居凶,下一步就是定義一個(gè)八卦爐,然后燒制人類侠碧。我們想象一下,女媧最可能給八卦爐下達(dá)什么樣的生產(chǎn)命令呢药蜻?應(yīng)該是“給我生產(chǎn)出一個(gè)黃色人種(YellowHuman類)”替饿,而不會是“給我生產(chǎn)一個(gè)會走、會跑踱卵、會說話惋砂、皮膚是黃色的人種”绳锅,因?yàn)檫@樣的命令增加了交流的成本,作為一個(gè)生產(chǎn)的管理者罗标,只要知道生產(chǎn)什么就可以了积蜻,而不需要事物的具體信息。通過分析宙拉,我們發(fā)現(xiàn)八卦爐生產(chǎn)人類的方法輸入?yún)?shù)類型應(yīng)該是Human接口的實(shí)現(xiàn)類丙笋,這也解釋了為什么類圖上的AbstractHumanFactory抽象類中createHuman方法的參數(shù)為Class類型御板。其源代碼如代碼清單8-5所示。

代碼清單8-5 抽象人類創(chuàng)建工廠

public abstract class AbstractHumanFactory{
public abstract<T extends Human>T createHuman(Class<T>c)敬鬓;
}

注意,我們在這里采用了泛型(Generic)础芍,通過定義泛型對createHuman的輸入?yún)?shù)產(chǎn)生兩層限制:

  • 必須是Class類型数尿;
  • 必須是Human的實(shí)現(xiàn)類。

其中的“?”表示的是诊杆,只要實(shí)現(xiàn)了Human接口的類都可以作為參數(shù)嫩实,泛型是JDK 1.5中的一個(gè)非常重要的新特性,它減少了對象間的轉(zhuǎn)換宰缤,約束其輸入?yún)?shù)類型慨灭,對Collection集合下的實(shí)現(xiàn)類都可以定義泛型球及。有關(guān)泛型的詳細(xì)知識,請參考相關(guān)的Java語法文檔筹陵。
目前女媧只有一個(gè)八卦爐镊尺,其實(shí)現(xiàn)生產(chǎn)人類的方法,如代碼清單8-6所示语稠。

代碼清單8-6 人類創(chuàng)建工廠

public class HumanFactory extends AbstractHumanFactory{
public<T extends Human>T createHuman(Class<T>c){
//定義一個(gè)生產(chǎn)的人種
Human human=null弄砍;
try{
//產(chǎn)生一個(gè)人種
human=(Human)Class.forName(c.getName()).newInstance()音婶;
}catch(Exception e){
System.out.println("人種生成錯(cuò)誤!")先口;
}
return(T)human瞳收;
}
}

人種有了,八卦爐也有了螟深,剩下的工作就是女媧采集黃土,然后命令八卦爐開始生產(chǎn)凡蜻,其過程如代碼清單8-7所示垢箕。

代碼清單8-7 女媧類

public class NvWa{
public static void main(String[]args){
//聲明陰陽八卦爐
AbstractHumanFactory YinYangLu=new HumanFactory();
//女媧第一次造人忠荞,火候不足帅掘,于是白人產(chǎn)生了
System.out.println("--造出的第一批人是白色人種--")修档;
Human whiteHuman=YinYangLu.createHuman(WhiteHuman.class);
whiteHuman.getColor()讥邻;
whiteHuman.talk()院峡;
//女媧第二次造人,火候過足鲫惶,于是黑人產(chǎn)生了

System.out.println("\n--造出的第二批人是黑色人種--")舱禽;
Human blackHuman=YinYangLu.createHuman(BlackHuman.class)字柠;
blackHuman.getColor()启妹;
blackHuman.talk()监徘;
//第三次造人六水,火候剛剛好,于是黃色人種產(chǎn)生了
System.out.println("\n--造出的第三批人是黃色人種--")睛榄;
Human yellowHuman=YinYangLu.createHuman(YellowHuman.class)想帅;
yellowHuman.getColor();
yellowHuman.talk()旨剥;
}
}

人種有了浅缸,八卦爐有了,負(fù)責(zé)生產(chǎn)的女媧也有了蚌父,激動(dòng)人心的時(shí)刻到來了梢什,我們運(yùn)行一下朝聋,結(jié)果如下所示。
--造出的第一批人是白色人種--

白色人種的皮膚顏色是白色的荔睹!

白色人種會說話言蛇,一般都是但是單字節(jié)。

--造出的第二批人是黑色人種--

黑色人種的皮膚顏色是黑色的吨拗!

黑人會說話婿斥,一般人聽不懂。

--造出的第三批人是黃色人種--

黃色人種的皮膚顏色是黃色的娇妓!

黃色人種會說話活鹰,一般說的都是雙字節(jié)只估。

哇蛔钙,人類的生產(chǎn)過程就展現(xiàn)出來了夸楣!這個(gè)世界就熱鬧起來了子漩,黑人石洗、白人、黃人都開始活動(dòng)了缕棵,這也正是我們現(xiàn)在的真實(shí)世界涉兽。以上就是工廠方法模式

工廠方法模式的優(yōu)點(diǎn)

首先,良好的封裝性别厘,代碼結(jié)構(gòu)清晰拥诡。一個(gè)對象創(chuàng)建是有條件約束的,如一個(gè)調(diào)用者需要一個(gè)具體的產(chǎn)品對象冗懦,只要知道這個(gè)產(chǎn)品的類名(或約束字符串)就可以了仇祭,不用知道創(chuàng)建對象的艱辛過程,降低模塊間的耦合没讲。
其次华弓,工廠方法模式的擴(kuò)展性非常優(yōu)秀。在增加產(chǎn)品類的情況下贰谣,只要適當(dāng)?shù)匦薷木唧w的工廠類或擴(kuò)展一個(gè)工廠類,就可以完成“擁抱變化”吱抚。例如在我們的例子中秘豹,需要增加一個(gè)棕色人種,則只需要增加一個(gè)BrownHuman類啄刹,工廠類不用任何修改就可完成系統(tǒng)擴(kuò)展凄贩。

再次,屏蔽產(chǎn)品類昵时。這一特點(diǎn)非常重要椒丧,產(chǎn)品類的實(shí)現(xiàn)如何變化,調(diào)用者都不需要關(guān)心句柠,它只需要關(guān)心產(chǎn)品的接口久橙,只要接口保持不變,系統(tǒng)中的上層模塊就不要發(fā)生變化缸榄。因?yàn)楫a(chǎn)品類的實(shí)例化工作是由工廠類負(fù)責(zé)的祝拯,一個(gè)產(chǎn)品對象具體由哪一個(gè)產(chǎn)品生成是由工廠類決定的。在數(shù)據(jù)庫開發(fā)中鹰贵,大家應(yīng)該能夠深刻體會到工廠方法模式的好處:如果使用JDBC連接數(shù)據(jù)庫碉输,數(shù)據(jù)庫從MySQL切換到Oracle亭珍,需要改動(dòng)的地方就是切換一下驅(qū)動(dòng)名稱(前提條件是SQL語句是標(biāo)準(zhǔn)語句)枝哄,其他的都不需要修改阻荒,這是工廠方法模式靈活性的一個(gè)直接案例。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侨赡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蓖宦,更是在濱河造成了極大的恐慌舶掖,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鲫售,居然都是意外死亡该肴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門秦效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阱州,“玉大人法梯,你說我怎么就攤上這事∫共眩” “怎么了铛绰?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵捂掰,是天一觀的道長镊叁。 經(jīng)常有香客問我晦譬,道長,這世上最難降的妖魔是什么敛腌? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任像樊,我火速辦了婚禮旅敷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涂滴。我一直安慰自己晴音,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布搁料。 她就那樣靜靜地躺著郭计,像睡著了一般椒振。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杠人,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天嗡善,我揣著相機(jī)與錄音,去河邊找鬼各吨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛横浑,可吹牛的內(nèi)容都是我干的屉更。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼欺冀,長吁一口氣:“原來是場噩夢啊……” “哼萨脑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起职车,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤悴灵,失蹤者是張志新(化名)和其女友劉穎仅淑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涯竟,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡庐船,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年筐钟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赋朦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡壹将,死狀恐怖诽俯,靈堂內(nèi)的尸體忽然破棺而出承粤,到底是詐尸還是另有隱情闯团,我是刑警寧澤仙粱,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布伐割,位于F島的核電站,受9級特大地震影響口猜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜川抡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一崖堤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧密幔,春花似錦、人聲如沸胯甩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恶复,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谤牡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工想许, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糜烹。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓漱凝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親愕乎。 傳聞我的和親對象是個(gè)殘疾皇子壁公,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 原文鏈接:http://blog.csdn.net/zhangerqing http://www.cnblogs....
    孤獨(dú)雜貨鋪閱讀 1,508評論 0 3
  • 設(shè)計(jì)模式匯總 一紊册、基礎(chǔ)知識 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,903評論 1 15
  • 一芳绩、設(shè)計(jì)模式的分類 總體來說設(shè)計(jì)模式分為三大類: 創(chuàng)建型模式撞反,共五種:工廠方法模式、抽象工廠模式遏片、單例模式、建造者...
    lichengjin閱讀 887評論 0 8
  • 愛無能吼拥,是一種病线衫。有的人與生俱來惑折,有的人后天養(yǎng)成。 是病就得治惨驶,于是踏上尋醫(yī)之旅。問過了那么多人屋确,還是不知道,醫(yī)何...
    槐月大人閱讀 308評論 0 1
  • 我其實(shí)并不贊同多談幾次戀愛才能長大這樣的說法焕数,每一次結(jié)束都是一場聲勢浩大的戰(zhàn)役刨啸,消耗我對生活的熱情,我寧愿把這個(gè)世...
    端子閱讀 185評論 0 0