2017-06-18 6 views
1

同じ機能を必要とする2つの同様のクラスがある場合。関数をグローバルに記述するか、各クラスの内部に同じ関数を2回書く方が良いでしょうか。 Ex。グローバル関数または多くのインスタンス関数

オプション1:

class A { 

    func buttonTapped() { 
     upvote(id) 
    } 

    func upvote(postID:String) { 
     // upvote the post 
    } 
} 

class B { 

    func buttonTapped() { 
     upvote(id) 
    } 

    func upvote(postID:String) { 
     // upvote the post 
    } 
} 

オプション2 2つのインスタンス機能:1つのグローバル関数

class A { 
    func buttonTapped() { 
     upvote(id) 
    } 
} 

class B { 
    func buttonTapped() { 
     upvote(id) 
    } 
} 

func upvote(postID:string) { 
     // upvote the post 
} 

またはより良いオプションがありますか?

答えて

3

どちらもお勧めできません。

データモデルクラスがあり、upvote関数がそのクラスの一部である必要があります。

class Post { 
    var postID: String 
    public private(set) var votes: Int 

    ... 

    func upvote() { 
     self.votes += 1 
    } 
} 

somePost.upvote() 
+0

ありがとう、これは興味深いです。 'getVotes()'メソッドを使用するのと比べて、getだけで投票を定義する利点は何ですか? –

+0

これは構造体上のクラスであるという利点もありますか? –

+0

「利点」はありませんが、意味的に 'votes'はプロパティではなく、関数でなければなりません。関数は、何らかの操作(例えば、上向きの投票)を意味するので、ゲッター関数を使うことができますが、プロパティを使う方がいいです。私は答えを更新したので、読み込み専用のプロパティを作成するより良い方法を見つけたことに注意してください。 – Paulw11

2

私は、共通の関数で "親"クラスを作成し、クラスAとBに "親"クラスを継承させます。このように:

class Parent { 
    func upvote(postID:String) { 
     // upvote the post 
    } 
} 

class A: Parent { 

    func buttonTapped() { 
     upvote(id) 
    } 

} 

class B: Parent { 

    func buttonTapped() { 
     upvote(id) 
    } 
} 
3

誰かが継承を示唆したが、あなたは常にcomposition over inheritance(ここでは、被写体の詳細:https://en.wikipedia.org/wiki/Composition_over_inheritance)を検討すべきであるとして、あなたはそれを呼ぶだろう

たぶんクラスがたくさんありますupvoteメソッドから利益を得ることができますか? 例えば、別のインスタンス化クローンを実装している場合、同じインタフェースをupvotingに使うことができるStoriesPostsがありますが、同じ親から継承するのは賢明ではありません。この場合

、我々はそのようなこと実現することができます。

protocol Votable { 
    func upvote() 
} 

extension Votable { 
    func upvote() { 
    // do upvoting 
    } 
} 

をそして、あなたはあなたのクラスにこのtraitを追加することができます:あなたが行く

class A: Votable { 
    func buttonTapped() { 
     upvote(id) 
    } 
} 

class B: Votable { 
    func buttonTapped() { 
     upvote(id) 
    } 
} 

そして、そこに:両方のための同じ機能を実装クラス継承を持たないクラス(または同じプロトコルに他の拡張を実装したい場合は、同じインタフェースを持つ異なるクラス)を使用できます。

編集:@ Paulw11が指摘したように、あなたはいつもより簡単な解決法に進むべきです。 Postsにのみupvoteメソッドが必要な場合は、継承や合成を混乱させず、メソッドが必要な場所に実装してから、製品の進化に応じてリファクタリングしてください。

関連する問題