首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >抽象工厂方法模式

抽象工厂方法模式
EN

Stack Overflow用户
提问于 2016-07-12 13:18:26
回答 1查看 128关注 0票数 0

我在网上看过几个视频和博客。我觉得我明白了一切,但是仍然在努力实现抽象工厂模式。以下是我的要求:

  1. 我有一个用户类,它应该给一个用户对象。
  2. 我的应用程序中有两种类型的用户,例如服务提供者(提供者)和服务接收者(消费者)。
  3. 这两种类型的用户之间有一些共同的属性,如姓名、电子邮件id、移动电话等。对于提供者类型,将有一些额外的属性。
  4. 提供者类型可以用于例如TaxiDriver或餐馆等。

我希望为这个用户类实现抽象工厂和工厂方法模式,这样应用程序就可以与用户模型分离,并且当应用程序想要一个类型为提供者或使用者的用户时,它应该得到正确的对象。

到目前为止我尝试过的是:

AbstracUserProtocol.h

代码语言:javascript
复制
@protocol AbstractUserProtocol

@required
@property(nonatomic, strong) id delegate;
@property(nonatomic, readonly, getter=isExist) BOOL exist;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *emailID;
@property (nonatomic, assign) NSInteger phoneNumber;

-(void)saveUserData;

-(void)retrievUserData;

@end

AbstractUser.h

代码语言:javascript
复制
@interface AbstractUser : NSObject <AbstractUserProtocol>

-(id)initWithType:(UserType)usrType;

@end

AbstractUser.m

代码语言:javascript
复制
@implementation AbstractUser
@synthesize delegate, exist, name, emailID, phoneNumber;

-(id)initWithType:(UserType)usrType
{
    self = nil;
    if (usrType == kConsumer) {
        self = [Consumer alloc]init];
    }
    else if (usrType == kProvider) {
        self = [ProviderFactory alloc] initWithServiceType:TaxiService];
    }

    return self;
}

-(void)saveUserData {
    [NSException raise:NSInternalInconsistencyException
             format:@"You have not implemented %@ in %@",
 NSStringFromSelector(_cmd), NSStringFromClass([self class])];
}

-(void)retrievUserData {

}

@end

现在,从ProviderFactory类创建了两个子类Consumer和AbstractUser。

Consumer.h

代码语言:javascript
复制
@interface Consumer : AbstractUser
@property (nonatomic, strong) NSString *address;
@end

ProviderFactory.h

代码语言:javascript
复制
@interface ProviderFactory : AbstractUser
-(id)initWithServiceType:(ServiceType)srvType;
@property(nonatomic, strong) NSString *ownerDetails;

@end

因此,无论将来什么时候,如果我的应用程序想要支持另一个业务用户,比如Taxi和Restaurant类型,那么我只需创建一个类并通过ProviderFactory类进行init。

对于抽象工厂模式,我的方法正确吗?感谢你的指导。

EN

回答 1

Stack Overflow用户

发布于 2016-07-13 00:54:46

根据你的后续问题,我编辑了答案。

我不完全确定您是否需要使用AbstractFactory来完成您想要完成的任务。AbstractFactory的基础是它允许您

提供一个接口,用于创建相关或依赖对象的系列,而无需指定它们的具体类(Gamma等人)。

以Gamma等人的“设计模式:可重用的面向对象软件的元素”为例。假设您正在创建一个工具箱,用于为文档编辑器构建用户界面。您可能有一堆小部件对象,如scroller、按钮、工具栏等,但您可能希望稍后向文档编辑器添加一种不同的外观。因此,您可以使用AbstractFactory提供一个接口来创建所有的小部件产品(即createScrollbarcreateButtons等)。但是为了改变外观,您可以子类抽象类并重写方法,这样,createScrollbar就会返回一个具有三维效果的滚动条。在另一种情况下,您可以子类抽象类以创建一个粉红色滚动条。这些选项是无穷无尽的,而且由于您的客户端代码并不关心滚动条的外观(客户端只关心它是否滚动文本),您可以轻松地添加未来的外观和感觉,而无需接触客户端代码。

在您的例子中,客户端关心它得到的是什么类型的AbstractUser,因为在某些情况下,它需要一个Customer,在某些情况下需要一个Provider。因此,无论哪种方式,如果将来您添加了一种新的用户,那么您的客户端代码就必须改变。

尽管如此,我认为最好的方法是创建一个抽象的用户基类,然后将其子类并将特定于用户的属性添加到子类中。这里是我的意思的一个例子。

AbstractUser.h

代码语言:javascript
复制
#import <Foundation/Foundation.h>

@interface AbstractUser : NSObject

@property(nonatomic, strong) id delegate;
@property(nonatomic, readonly, getter=isExist) BOOL exist;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *emailID;
@property (nonatomic, assign) NSInteger phoneNumber;

@end

Consumer.h

代码语言:javascript
复制
#import "AbstractUser.h"

@interface Consumer : AbstractUser

@property (strong, nonatomic) NSString *address;

@end

ViewController.m

代码语言:javascript
复制
#import "ViewController.h"
#import "Consumer.h"
#import "Provider.h"

@interface ViewController ()

@property (strong, nonatomic) Consumer *consumer;
@property (strong, nonatomic) Provider *provider;

@end

@implementation ViewController

- (void)viewDidLoad
{

    [super viewDidLoad];

    _consumer = [[Consumer alloc] init];
    _provider = [[Provider alloc] init];

    self.consumer.name = @"Jason";
    self.consumer.address = @"some address";

    self.provider.name = @"Stack Overflow";

@end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38330057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档