デザインモードシリーズ・クラス爆発のブリッジモード


謎の微笑み
C兄の丹念な指導を経て、ニュースセンターはついにオンラインになりました!コードは半月間実行され、安定したバグはありません.王小二は頬杖をついて、コードを見て、謎の微笑みが輝いた^^.追求のある私たちとして、この时の楽しみは自分だけが理解できるかもしれません.
メッセージセンターの再構築
ある朝、小二は集中して、キーボードの間で指をリズムよくたたいて、1行のコードが画面に躍り出た.いつの間にか、ボスは二ちゃんの後ろに半日立っていた...
「二ちゃん、前のインフォメーションセンターは君が作ったんだろう?」「ええ、そうです」
「はい、サービス分割をしています.メッセージセンターは汎用的なサービスなので、メッセージセンターを分解して、下位サービスにしたいと思います」「よし、そうだったはずだ!」
「ええと、具体的にメッセージを送るロジックは、javaグループの同級生に任せて書きます.約束のデータフォーマットに従って、データpushをキューに入れて、javaのほうで消費すればいいだけです」「ええ…いいですよ.行列は何で実現しますか」
「キューについては、redisとmqの2つの方法をサポートする必要があります.つまり、私はredisキューにpushデータをサポートするだけでなく、mqにpushデータをサポートしますか?」
「はい、そうです.これをよく設計してください.」「はい、安心してください.ボス!」
設計クラス図
二ちゃんはこの2,3日デザインモデルを研究しています.再構築の新しいニーズを受けた以上、しっかりと活躍しましょう.
やがて、二ちゃんは大体の考えを出しました.
メッセージを送信して、3つのステップに分けます:1、異なるメッセージ(メール、微信)はそれぞれのデータフォーマットと内容を組み立てます;2、メッセージは異なる方法(redis、mq)でキューにプッシュすることができる.3、send()メソッドを使用して、まずステップ1からデータを取得し、ステップ2のメソッドpushを対応するキューに利用する.
考えがはっきりして、小二はすぐにクラス図を描いた.
小二は自分が設計したクラス図を何度も繰り返し見た:うん、基本的に需要を実現した.1、メッセージはメールメッセージと微信メッセージ(SmsMessageとWechatMessage)2に分けられ、同じメッセージはredisで送信してもよいし、Mqで送信してもよい.大丈夫だgreat!
類爆発
いつものように、大きなデザインは、やはりC兄さんにチェックしてもらいます.次男はC兄を見つけて、自分のニーズと設計を詳しく紹介した.
「うん…二ちゃん、問題は解決したけど、デザインはちょっと問題があるみたいだね」「え?質問?Cさんに教えてもらいます」
「これは類爆発を引き起こす!」「何?類は爆発するの?冗談じゃない」
「ははは、信じないの?さあ、クラスがどのように爆発したのか見せてあげましょう.Emailメッセージのタイプを追加する必要があるとしたら、クラス図を設計してください」「はい、C兄さん、ちょっと待って、すぐに設計してください」
間もなく、王小二は新しいクラス図を設計した.
「二ちゃん、赤い部分はあなたが追加した3つのクラスです.」「ふむふむ、はい!」
「よし、その上で、Mysqlキューの送信方法を増やしてくれ」「よし!」
次男は新しいクラス図を持ってC兄を見つけた.
「二ちゃん、さっきメッセージのタイプと送信方法を追加させただけですが、全部でいくつかのクラスが追加されましたか?」「1.2.3.6、全部で6つのクラスが追加されました!」
「はい、あなたは今全部で13のクラスを持っています.メッセージのタイプと送信方法を追加したら、何のクラスを追加しますか?」「ええと、8つのクラスが追加されます.その時になると13+8=21のクラスになります...」
「類が多すぎて、爆発したのかな?ははは、これが類爆発だ」「確かに、類が多すぎる!でも、どうやって解決するのかな?...」
ブリッジモード登場
「二ちゃん、前に話した四人団の三つのアドバイスを覚えていますか?」「うん、覚えてる:
 
 1 、      ;
 2 、        ,      ;
 3 、         。


「はい、この3つです.見てください.あなたのデザインは上記の原則に反しています.」C兄は言った.「えっ?本当に違反してるの??」王小二はしばらく見ていたが...
「ああ...はい、C兄さん、確かに.第2点に違反しました.私のクラス図で使われているのは継承です.この継承間の結合性が高すぎて、膨大です!」「はい、今ブリッジモードで彼を取り外します」
「まずBridgeモードの基本的な定義をお話ししましょう!」「はい、C兄さん!」
ブリッジモード、すなわちブリッジモード、四人団は「抽象部分とその実現部分を分離し、独立して変化させる」と述べている.
「え?C兄さん、全然わからないって…」「ははは、普通、あなたがすぐに理解できるのはおかしいですね.この言葉は初心者に誤解されやすいので、私たちは実践しながら、この定義を説明します.」
「二ちゃん、さっき四人団が『変化の点を見つけてカプセル化する』と提案したんじゃないですか.あなたは今、あなたのデザインの中でこれらの変化の点を見つけて、カプセル化しています」「はい、C兄さん、考えてみます」
次男はしばらく考えた.「変化の点は2つある.一つはメッセージのタイプが変化し、もう一つは送信方法が変化する.」考えた後、二ちゃんはすぐに絵を描いた.「ええ、いいですね.二ちゃん、説明してください」
小二は「変化点は2つある.1つはメッセージタイプ[Sms,Wechat...]である.一つは送信方式[redis,mq...]である.
だから私は彼らをそれぞれカプセル化して、2つの独立した抽象類になりました:MessageとSendType.
Messageクラスは、自分のメッセージタイプのデータ(combine_data())を組み立て、送信します(send()).SendTypeクラスは、データpush(push_to_queue())を対応するキューに入れる役割を果たす."
「いいですね.二ちゃん、私はあなたのクラス図に基づいて拡張して、あなたはクラス爆発の問題をどのように解決するか知っています.」「わあ、はい、C兄さん!」
しばらくして、C兄は2番目の基礎の上で、完全な類図を描きました:“よく分からないで、C兄はあなたが説明してください!”
C兄は「二ちゃん、ほら、メッセージには2つのタイプがあります.メールと微信です.
しかし、メールや微信にかかわらず、彼らは自分のメッセージのフォーマットと内容を知っていなければならない.そして、彼らは自分を送信しなければなりません.つまり、pushを対応するキューに送信しなければなりません.
どうやってキューにプッシュしますか?これにはredisキューとmqキューの2つの実装方式がある.すなわち,送信という動作を実現するには,どのように送信するかを知らなければならない.
ここを見て、私はあなたが最初に設計したクラス継承の方法を使っていません:ここの抽象部分:つまりMessageの抽象です;ここでの実装部分は,SendTypeの実装である.
抽象部分と実装部分の間に橋を架け、抽象部分が実装部分のオブジェクトを参照できるようにするのがブリッジモードです.
このようにオブジェクトの組み合わせを使う方法は、特に柔軟です."
「わあ、C兄さん、この橋は威力が大きいですね.」「そうですね.ブリッジ・モードは難しいですが、もっと役に立ちます.新しいメッセージ・タイプを追加しても、新しい送信方法を追加しても、彼らの間には結合がなく、独立して変化することができます」
「そうですね.これで爆発的な問題もなくなり、冗長性が減り、コードのメンテナンスがよくなりました.」「そうなんだ!」
コード実装
bridgeモードの威力を目撃した後、小二は待ちきれずに対応する偽コードを書いた.
「C兄さん、私が書いたコードの考えを見てくれませんか?」「はい、見てみます」
send_type_obj=$send_type_obj;
        $this->data=$data;
    }

    //   :           ,          
    abstract public function combine_data();

    //       (      , push       )
    public function push_to_queue($data){
        if($this->send_type_obj instanceof SendType){
            $this->send_type_obj->push_to_queue($data);
        }
    }

    //    
    public function send(){
        $combined_data=$this->combine_data();
        $this->push_to_queue($combined_data);
    }
}

//     
class SmsMessage extends Message {
    //        
    public function combine_data(){
        return 'sms combined data:'.$this->data;
    }
}

//     
class WechatMessage extends Message {
    //        
    public function combine_data(){
        return 'wechat combined data:'.$this->data;
    }
}

//       
abstract class SendType{
    abstract public function push_to_queue($data);
}

//Redis      
class RedisSendType extends SendType {
    //    push   redis    ,    
    public function push_to_queue($data)
    {
        echo  $data." has sent by redis queue
"; } } //Mq class MqSendType extends SendType { // push mq , public function push_to_queue($data) { echo $data." has sent by mq queue
"; } } /************Test Case*************/ // $redis_send_obj=new RedisSendType(); $mq_send_obj= new MqSendType(); // redis $sms_redis_obj=new SmsMessage($redis_send_obj,'123'); $sms_redis_obj->send(); // redis $wechat_redis_obj=new WechatMessage($redis_send_obj,'456'); $wechat_redis_obj->send(); // mq $sms_mq_obj=new SmsMessage($mq_send_obj,'789'); $sms_mq_obj->send(); // mq $wechat_mq_obj=new WechatMessage($mq_send_obj,'100'); $wechat_mq_obj->send();

「ええ、故障していないようですが、運行結果を見てみます」「はい、C兄さん、これは運行結果です」
「ははは、確かに大丈夫だよ.いいね、二ちゃん!」"C兄の指导の良くて、C兄に感谢して、また1种の强大な设计のモードを学びました!"
締めくくり
設計モードがこのように強く、bridgeから一般的ではないことがわかります.では、いったい何がデザインモデルなのでしょうか.通俗的な定義はありますか?
実は、通俗的に言えば:
設計モードは,特定の問題に対して繰り返される解決策であり,抽象化,テンプレート化される.そして時間が経つにつれて、これは優れた解決策であることが歴史的に証明された.
だから、王小二と一緒にデザインをよく勉強しましょう.あなたは結局「左手コード右手詩」の天地に入ると信じています.^^;
転載声明:本文は「チャットコード」から転載し、「talkpoem」を検索すれば注目できる.
「トークコード」に注目して、「左手コード右手詩」のことを話しましょう.