通过一个计算器的例子,了解设计模式中的工厂模式

计算器实例方法声明

@interface ViewController : UIViewController

{

BOOL bBegin;

BOOL backOpen;

BOOL cptOpen;

BOOL secOpen;

double fstOperand;

double sumOperand;

NSString *operator;

}

@property (strong, nonatomic) IBOutlet UITextField *display;

@property (strong, nonatomic) IBOutlet UILabel *showSpecial;

@property (strong, nonatomic) IBOutlet UILabel *showFoperator;

/**

*  初始化清屏方法

*/

-(void)clearDisplay;

/**

*  回退方法

*/

-(void)backSpace;

/**

*  双操作数运算方法声明

*/

-(void)inputDoubleOperation:(NSString *)dbopt;

-(void)inputSingleOperator: (NSString *)sgopt; // 单操作数运算方法声明

/**

*  增加。方法声明

*/

-(void)addDot;

/**

*  增加正负号方法声明

*/

-(void)addSign;

/**

*  数字输入方法声明

*/

-(void)inputNumber:(NSString *)nbstr;

/**

*  按键管理事件声明

*/

- (IBAction)btnClicked:(id)sender;

@end

类实现

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad

{

_display.text = @"";

_showSpecial.text = @"";

_showFoperator.text = @"";

operator = @"=";

fstOperand = 0;

sumOperand = 0;

bBegin = YES;

cptOpen = NO;

secOpen = NO;

}

- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];

}

- (IBAction)btnClicked:(id)sender

{

UIButton *btn = (UIButton *)sender;

NSInteger tag = btn.tag;

switch (tag) {

case clearBtn:

[self clearDisplay];

break;

case backBtn:

[self backSpace];

break;

case plusBtn: // +    3

case subBtn: // -    4

case mulBtn: // x    5

case divBtn: // ÷    6

case equalBtn: // =    9

[self inputDoubleOperation:btn.titleLabel.text];

break;

case dotBtn:

[self addDot];

break;

case signBtn:

[self addSign];

break;

//数字分支

default:

[self inputNumber:btn.titleLabel.text];

break;

}

}

-(void)clearDisplay

{

_display.text = @"";

_showFoperator.text = @"C";

operator = @"=";

fstOperand = 0;

sumOperand = 0;

bBegin = YES;

cptOpen = NO;

}

-(void)backSpace

{

_showFoperator.text = @"←";

if (backOpen)

{

NSLog(@"回退回退回退%d",backOpen);

if (_display.text.length == 1)

{

_display.text = @"";

}

else if (![_display.text isEqualToString:@""])

{

_display.text = [_display.text substringToIndex:_display.text.length -1];

}

}

}

-(void)addDot

{

_showFoperator.text = @".";

if(![_display.text isEqualToString:@""] && ![_display.text isEqualToString:@"-"])

{

NSString *currentStr = _display.text;

BOOL notDot = ([_display.text rangeOfString:@"."].location == NSNotFound);

if (notDot)

{

currentStr= [currentStr stringByAppendingString:@"."];

_display.text= currentStr;

}else{

_display.text= currentStr;

}

}

}

-(void)addSign

{

_showFoperator.text = @"+/-";

if(![_display.text isEqualToString:@""] && ![_display.text isEqualToString:@"0"] && ![_display.text isEqualToString:@"-"])

{

double number = [_display.text doubleValue];

number = number*(-1);

_display.text= [NSString stringWithFormat:@"%g",number];

if(bBegin)

{

sumOperand = number;

}

}

}

-(void)inputNumber:(NSString *)nbstr

{

backOpen = YES;

cptOpen = NO;

NSLog(@"输入数字的时候%d",backOpen);

if(bBegin)

{

_showFoperator.text = @"";

_display.text = nbstr;

}

else

{

_display.text = [_display.text stringByAppendingString:nbstr];

}

bBegin = NO;

}

-(void)inputDoubleOperation:(NSString *)dbopt

{

_showFoperator.text = dbopt;

backOpen = NO;

NSLog(@"点击双操作符时的时候%d",backOpen);

if(![_display.text isEqualToString:@""])

{

fstOperand = [_display.text doubleValue];

if(bBegin)

{

operator = dbopt;

}

else

{

if([operator isEqualToString:@"="])

{

sumOperand = fstOperand;

}

else if([operator isEqualToString:@"+"])

{

sumOperand += fstOperand;

_display.text = [NSString stringWithFormat:@"%g",sumOperand];

}

else if([operator isEqualToString:@"-"])

{

sumOperand -= fstOperand;

_display.text = [NSString stringWithFormat:@"%g",sumOperand];

}

else if([operator isEqualToString:@"x"])

{

sumOperand *= fstOperand;

_display.text = [NSString stringWithFormat:@"%g",sumOperand];

}

else if([operator isEqualToString:@"÷"])

{

if(fstOperand!= 0)

{

sumOperand /= fstOperand;

_display.text = [NSString stringWithFormat:@"%g",sumOperand];

}

else

{

_display.text = @"nan";

operator= @"=";

}

}

bBegin= YES;

operator= dbopt;

}

}

}

- (void)inputSingleOperator: (NSString *)sgopt

{

_showFoperator.text = sgopt;

backOpen = NO;

if(![_display.text isEqualToString:@""])

{

operator = sgopt;

fstOperand = [_display.text doubleValue];

if([operator isEqualToString:@"x²"])

{

sumOperand = pow(fstOperand , 2);

_display.text= [NSString stringWithFormat:@"%g",sumOperand];

}

else if([operator isEqualToString:@"ln"])

{

sumOperand = log(fstOperand);

_display.text= [NSString stringWithFormat:@"%g",sumOperand];

}

else if([operator isEqualToString:@"log"])

{

sumOperand = log10(fstOperand);

_display.text= [NSString stringWithFormat:@"%g",sumOperand];

}

}

bBegin = YES;

}

@end

以下内容转载于网络,用于对工厂模式更好的理解。

关于工厂设计模式的个人理解:就是为了创建对象的.

一般我们在iOS的开发过程当中,经常使用alloc来创建对象,假如我们需要创建100个button对象,那么也就是我们需要alloc100次,才能实现我们的目标.或许机智的你,会说"那还不简单,写一个for循环,alloc一次不就可以了",但是实际开发过程中如果这100个button并不是创建在一个地方那你怎么办呢?你只能照本宣科的写100次alloc来解决这个问题.

再者,如果我们创建对象完了以后,需要去给这些对象去添加一些固有的属性跟值,比喻说:"某某工厂里面的员工",那么我们也就要多些100次这样的代码,去声明他的属性了.

如果我们在一个-(void)createObj方法,把创建的对象以及它的工厂属性写到这个方法里面去,我们是不是会把多行代码要完成的事情,通过一句代码搞定呢?

言外之意,也就是我们可以把alloc创建一个对象写到一个方法里面去,直接调用这个方法就 可以了.这就是我对工厂方法的个人理解.

代码结构如下:

声明一个类:动物类

@interface Animal:NSObject

@proterty(nonatomic,strong) NSString *name;

@end-(void)running;

@interface Dog:Animal

@end

@interface Cat:Animal

@end

常见对象的工厂类:

.h

@interface AnimalFactory:NSObject

+(Dog *)createDog;

+(Cat *)createCat;

@end

.m

+(Dog *)creatDog{

[  Dog * dog = [Dog alloc] init];

dog.name = @"WangCai";

return dog;

}

+(Cat *)createCat{

Cat * cat = [Cat alloc]init];

return cat;

}

Main.m文件里面

Dog *dog=[AnimalFactory createDog];

Cat *cat=[AnimalFactory createCat];

这就是简单的工厂方法.

现在我们创建100个对象,也就是需要把把这个方法写100次, 那么现在我们有这样的一个需求,如果我们需要把我们用工厂方法创建的对象的名字换掉呢?那么也就是说我们需要把,这个100   处地方的Dog换成Cat,这样做就很麻烦,在实际项目中面临的问题就是代码维护起来特别麻烦.举个例子,比喻说我们用到的第三方的一个框架,AFNnetWork ,如果我们再使用的过程当中,没有去建立自己的一个工具类来封装AFN,那么加入有一天,AFN升级了,改版了,甚至是api都换掉了,那么我们用到AFN的每个控制器里面关于AFN的地方都会出现各种红色的错误提示,就像横尸遍野搬的场景.

现在,如果您使用了工厂设计模式就能很好的解决这个问题了.

工厂方法模式是为每一个要创建的对象所在的类都相应地创建一个工厂

代码如下

@interface AnimalFactory:NSObject

-(Animal*)createAnimal;

@end;

Dog工厂类

@interface DogFactory:AnimalFactory;

@implementation DogFactory

-(Animal *)createAnimal{

retrurn [[Dog alloc]init];

}

@end

Cat工厂类

@interface CatFactory:AnimalFactory;

@implementation Cat Factory

-(Animal *)createAnimal

retrurn [[Cat alloc]init];

}

@end

Main.m

AnimalFactory *dogFactory=[[DogFactory alloc]init];

Animal *animal1=[dogFactory createAnimal];

[animal1 laugh];

Animal *animal2=[dogFactory createAnimal];

[animal2 laugh];

…….

Animal *animal100=[dogFactory createAnimal];

[animal100 laugh];

这样话如果要把100个Dog改为Cat的话,只需要吧DogFactory改为CatFactory就可以了

但是需要注意的是:

1.使用工厂方法的对象都必须继承同一个父类

2.要创建的对象在100个地方的类必须一样

以上这些方法,纯属于个人感悟.如果有不对的地方,希望大家及时提出,我好更正.

文/Ruo兮(简书作者)
原文链接:http://www.jianshu.com/p/9a7168acf606
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2024-12-10 07:01:50

通过一个计算器的例子,了解设计模式中的工厂模式的相关文章

设计模式初探—简单工厂模式

为什么要学习设计模式? 可重用.可维护.可扩展.灵活性好 什么是简单工厂模式? 从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现. 简单工厂模式的好处? (1)将具体业务和实现进行分离 (2)将多个具体业务之间进行解耦 解决的问题? 单独的类来创造

01.设计模式_简单工厂模式

转载自  http://www.cnblogs.com/zhili/p/SimpleFactory.html 一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式--简单工厂模式. 二.简单工厂模式的介绍 说到简单工厂,自然的第一个疑问当然就是什么是简单工厂模式了? 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责生产对象的一个类, 我们平常编程

C#设计模式(2)——简单工厂模式

一.引言 这个系列也是自己对设计模式的一些学习笔记,希望对一些初学设计模式的人有所帮助的,在上一个专题中介绍了单例模式,在这个专题中继续为大家介绍一个比较容易理解的模式——简单工厂模式. 二.简单工厂模式的介绍 说到简单工厂,自然的第一个疑问当然就是什么是简单工厂模式了? 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责生产对象的一个类, 我们平常编程中,当使用”new”关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我

C#设计模式(2)-简单工厂模式

引言 上一遍中介绍了设计模式中的单例模式-C#设计模式(1)-单例模式,本篇将介绍简单工厂模式,也是比较容易理解的一种模式:本文将以多数据库操作为例进行讲解: 简单工厂模式简介 什么是简单工厂模式? 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因此简单工厂模式又被称为静态工厂方法模式,它属于创建型模式. 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责

Java设计模式之二工厂模式

在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法.本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式.工厂方法和抽象工厂模式. 简单工厂模式 简单工厂模式是属于创建型模式,又叫做静态工厂方法模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.调用只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类工厂的子类. 可以说是工厂模式中最简单的一种. 打个比方,我们在电脑经常玩游戏,我们只需要告诉电脑我们要玩什么游戏,电脑就会打开这个游戏,我们并不需要关心游戏是

Android设计模式之一个例子让你彻底明白工厂模式(Factory Pattern)

提出疑问 这几天研究工厂模式的时候,看到网上的一些文章中举的例子我就很疑惑,我相信这也是许多人的疑惑:工厂模式的功能就是创建实例,我们创建实例直接new不就完了吗,干嘛还得再封装一层工厂类,然后用工厂类再去new出这个实例?这不多此一举吗? 比如我看到这样的例子,我们的用户分为金牌用户和银牌用户,我们要创建一个金牌用户或者银牌用户. 定义一个用户接口 public interface ICustomer { String describe(); } 金牌用户实现类 public class Go

从“假如有以下几种价格10,20,50,请你代码实现将他们排序输出”看着设计模式中的策略模式

今天重温了一下策略模式,将自己的一些感悟与大家分享...本人只是技术渣渣,所理解的东西的难免会有很大的局限性甚至是错误,还请各位带着批判的眼光去看待....不喜请勿吐槽 定义:策略模式属于设计模式中的对象行为型模式,它将用到的算法单独抽象成一个单独的类.通常,我们在多个类完成同一件事情,仅仅完成的方式不同时,我们可以考虑使用这种设计模式. 举例:相信,很多人在看到"假如有以下几种价格10,20,50,请你代码实现将他们排序输出"这种题目的时候,很快就写出了以下代码,写之前还不忘了问一下

学习大话设计模式01_简单工厂模式(简易计算器)

1 /** 2 * 面向对象(运算类) 3 * 简易计算器 4 * @author Monica 5 * 6 */ 7 public class Operation { 8 private double numberA = 0; 9 private double numberB = 0; 10 11 //虚函数 12 public double GetResult() { 13 double result = 0; 14 return result; 15 } 16 17 public doub

Java演示设计模式中的单件模式的代码

下边代码内容是关于Java演示设计模式中的单件模式的代码,应该是对小伙伴们有所用处. public class SimpleSingleton { private static SimpleSingleton singleInstance = new SimpleSingleton(); private SimpleSingleton() { } public static SimpleSingleton getInstance() { return singleInstance; } } 调用