1

人々がオブジェクトをどのように設計し、プログラムで設計パターンを使用するのか疑問に思っています。

例えば:

2 種類の車 (BMW、Benz) と 2 つの色 (Black、White) があるとしますが、color オブジェクトは既に 2 つのメソッドで存在しています。

[Color initWithBlack];
[Color initWithWhite];

.h ファイルで 2 つのメソッドを定義する

- (Car *)makeWithType:(NSString *)type;
- (Car *)makeWithType:(NSString *)type andColor:(NSString *)color;

.m ファイル内

- (Car *)makeWithType:(NSString *)type
{
    // default is black
    return [self makeWithType:type andColor:@"black"];
}

- (Car *)makeWithType:(NSString *)type andColor:(NSString *)color
{
    Car *car = [[Car alloc] init];
    car.type = type;
    switch(color) {
        case "black":
            [car addColor:[Color initWithBlack]];
            break;
        case "white":
            [car addColor:[Color initWithWhile]];
            break;
        default:
            break;
    }
    return car;
}

オブジェクトを定義および実装する適切な方法ですか?

疎結合または密結合の依存関係はありますか?

きつい場合、カップリングを減らすために設計をどのように改善できますか?

4

2 に答える 2

2

オブジェクトを作成するオブジェクト/クラスがある典型的なFactory patternのように思えます。この場合、それを呼び出すことがCarsFactoryでき、メソッドはクラス メソッド (+) であり、インスタンス (-) ではないため、次のようになります。

+ (Car *)makeWithType:(NSString *)type;
+ (Car *)makeWithType:(NSString *)type andColor:(NSString *)color;

また、 Apple が独自のクラスでそれをどのように適用しているかを確認することもできます。これは、Jon Reid による興味深い記事でもあります。

于 2013-11-08T09:06:12.943 に答える
1

車のタイプ自体が車のクラスに何も追加しないと仮定すると、あなたが持っているものはある程度正しいでしょう。

そこにはいくつかの欠陥があります。まず第一に、- (Car *)makeWithType:(NSString *)type;メソッドはおそらくクラス メソッドであり、インスタンス メソッドではないはずです。それをインスタンスメソッドにすることは、ダミーカーを初期化してから正しいものを作成する必要があるため、それを持つ目的を無効にします。

さらに、ある時点で、BMW にはベンツにはない特性があることがわかった場合は、サブクラス化がより適切になります。車を作成するための同様のクラス メソッドを保持することもできますが、その中で正しいサブクラスを決定し、代わりにそのクラスのインスタンスを返すことに注意してください。これは、クラス クラスターと呼ばれるものです。たとえば、UIButton はクラス クラスターであり、型を取り、指定された型に適した具体的なサブクラスを返します。

車のメーカーや色などの定数がある場合、色オブジェクトが何かをしない限り、文字列やオブジェクトの代わりに列挙型を使用する方がよいでしょう。これにはいくつかの利点があります。1 つ目は明確さです。現時点では、Car ヘッダー ファイルを見たときに、どのタイプ/色が利用可能かを理解していません。列挙型を使用すると、使用可能な値をすぐに確認できます。2 番目は正確さです。文字列では間違いが起こりやすく、コンパイラによる正確さのチェックはありません。列挙型では、定義されていない値を使用すると大きな赤い警告が表示されます。

結論として、Car クラスに使用するヘッダーを次に示します (BMW と Benz は単純な型であり、車に特別な意味を追加しないと仮定します)。

typedef NS_ENUM(NSUInteger, CarMake) {
    CarMakeBMW,
    CarMakeBenz,
};

typedef NS_ENUM(NSUInteger, CarColor) {
    CarColorBlack,
    CarColorWhite,
};

@interface Car : NSObject

+ (Car *)makeWithType:(CarMake)make;
+ (Car *)makeWithType:(CarMake)make andColor:(CarColor)color;

@end

本当に Color オブジェクトを使用する必要がある場合 (ところで、initWithWhi(t)eメソッド名にタイプミスがあることに注意してください)、その色を参照する文字列ではなく、その色をメソッドに渡す必要があります。または、渡された列挙値に基づいてクラスメソッドで適切なオブジェクトを作成することにより、上記のヘッダーとカラーオブジェクトを組み合わせて使用​​します。

于 2013-11-08T09:14:39.483 に答える