デザインパターンとコードの構造の分析

デザインパターンとコードの構造

スクエア、デザインパターン入門

  「デザインモード」のコンセプトは、最初に1990年代のソフトウェア工学の導入後、建設部門から来ています。

  また、また、デザインパターンとして知られているデザインパターンとして知られているソフトウェアのデザインパターンは、カタログ作成、コードの設計経験の要約の後、ほとんどの人に知られ、繰り返し使用のセットです。これは、ソフトウェアの設計プロセスを繰り返し発生中の問題だけでなく、問題の解決策のいくつかを説明します。言い換えれば、それは特定の問題を解決するための一連のルーチンで、前任者のコード設計の経験をまとめたものである、一定の普遍性を持って、繰り返し使用することができます。その目的は、コードの再利用性、信頼性、可読性やコードを強化することです。

 

まず、デザインパターン要素、原則と分類

  ソフトウェアのデザインパターンので、人々がより簡単かつ容易にすることができ、通常、次の基本的な要素を含んで成功したデザインや建築、再利用のこと:パターン名、別名、動機、問題、解決策、効果、構造、ロールモデル、パートナーシップを、実装、拡張知られているアプリケーション、ルーチン、モードと関連するモードの適用。

  デザインパターンは、次の設計原則があります。

 

    原則閉鎖 :オープン拡張をものの変形のため閉鎖 あるいはリヒター原理:サブクラスは、親クラスの機能を拡張することができるが、親クラスの本来の機能は変更できません依存性逆転原理:プログラミングを指向するインターフェースを介して、クラス間の結合を減少させます単一責任の原則オブジェクト(クラス)あまりにも多くの責任を仮定するべきではありません。隔離インターフェースの原則を:インタフェースより小さく、より具体的に分割肥大化したインターフェイスデメテル:だけ教えていない、あなたの友人と直接話「見知らぬ人」トーク原則を多重合成:達成するために、継承の使用を検討する前に続く会合または重合の組み合わせを使用することが可能な限り達成するために
    
    
    
    
    
    
  1995年、エリック・ガマ(ErichGamma)、リチャード・ヘルム(リチャード・ヘルム)、ラルフ・ジョンソン(ラルフ・ジョンソン)、ジョン・威利斯迪斯(ジョン・ブリシディース)と他の4人の著者(デザインパターン:再利用可能の要素:「オブジェクト指向における再利用のためのデザインパターン」共著オブジェクト指向ソフトウェア) 、デザインモードイベントの分野で画期的な出来事である23デザインモードを、含まれている本を。 今日までは、狭いデザインモードまたは23の古典的なデザインパターンは、このチュートリアルで説明します。
  生成に関するパターン、行動パターンと機関型モード:一般的に、この23個のデザインパターンは、一般的に3つのカテゴリーに分類されます。
  スキーマを作成することは、単にオブジェクトを作成するために使用されます。シングルケースモデル、Builderパターン、Factory Methodパターン、Abstract Factoryパターン、プロトタイプモデル:5つのカテゴリがあります。
  行動モデルは、主にオブジェクトクラスまたはどのように相互に作用して、どのように責任を割り当てることを示します。モードを説明するための戦略パターン、テンプレートメソッドパターン、Observerパターン、反復モード、責任のチェーン・モード、コマンドモード、メモモード状態モード、ビジターパターン、仲介モデル:11種類の合計。
  構造モデルは、主に、併用治療クラスまたはオブジェクトのために使用されます。7の全アダプタモード、装飾的なパターン、プロキシモード、アスペクトモード、ブリッジモード、複合モード、フライ。
 
第二に、オブザーバーモード(Facadeパターン)の紹介
図1に示すように、定義されたオブザーバーパターン
  多数の複雑なサブシステム、パターンがより容易にアクセスするサブシステムへの一貫したインターフェースを提供することによって、一種。モデルは内部サブシステムの具体的な詳細を気にしない外部、外部アプリケーションに統一されたインタフェースを持って、それが大幅に、アプリケーションの複雑さを軽減プログラムの保守性を改善するだろう。
  送信の対象の状態が変更されたときに簡単に説明すると間オブザーバーパターンは、複数のオブジェクトの依存性を定義し、すべてのそれに依存通知し、自動的に更新されます。
 
の2、および構造
   外観(ファサード)モデルは、以下の主要な役割で構成されています。
  1. 外観(ファサード)役割:外部インターフェイスサブシステムの公倍数を提供します。
  2. サブシステム(サブシステム)役割:顧客は、文字の外観を介してアクセスすることができ、システムの機能の一部を実現します。
  3. 客户(Client)角色:通过一个外观角色访问各个子系统的功能。
模式图
 
3,代码实现
  由于一时没有找到合适的代码示例,再加上熬夜看了巴萨大胜马洛卡有点兴奋,所以直接按照网上的模板实现了一个模拟足球比分推送的观察模式代码。
  首先要做的就是创建观察者和主题的抽象基类。通过纯虚函数规定其派生类所需提供的接口。
 1 // 观察者基类
 2 class Observer_base {
 3 public:
 4     virtual ~Observer_base() {}
 5 
 6     // 显示名字
 7     virtual const string get_name() const = 0;
 8 
 9     // 更新
10     virtual void update(const string & words) = 0;
11 
12     // 重载==运算符,从订阅列表删除元素的时候使用
13     virtual bool operator == (const Observer_base* outer) const = 0;
14 };
15 
16 
17 
18 // 被观察者基类
19 class Target_base{
20 public:
21     virtual ~Target_base() {}
22 
23     // 添加订阅者
24     virtual void add_one_follower(Observer_base* outer) = 0;
25 
26     // 删除订阅者
27     virtual void rm_one_follower(Observer_base* outer) = 0;
28 
29     // 更新发布内容,即本类中的words变量
30     virtual void set_string(const string& words) = 0;
31 };
 1 // 被观察者的一个具体类,比如某队比分推送 
 2 class Target_scorePush: public Target_base {
 3 private:
 4     // 观察者集合
 5     set<Observer_base*> followers;
 6     
 7     // 被观察者发布的内容
 8     string words;
 9 
10 public:
11     // 添加订阅者
12     void add_one_follower(Observer_base* outer) {
13         followers.insert(outer);
14         cout << outer->get_name() << "成功订阅!" << endl;
15     }
16 
17     // 删除订阅者
18     void rm_one_follower(Observer_base* outer) {
19         set<Observer_base*>::iterator it; 
20         for ( it = followers.begin(); it != followers.end(); ++it) {
21 
22             if (**it == outer) {
23                 followers.erase(it);
24                 cout << outer->get_name() << "删除成功!" << endl;
25                 break;
26             }
27 
28             cout << outer->get_name() <<"删除失败,预删除用户未在订阅列表中。" << endl;
29         }
30     }
31 
32     // 发布新的内容
33     void set_string(const string& words) {
34         // 更新内容
35         this->words = words;
36         cout << "巴萨最新比分推送: " << this->words << endl;
37         
38         // 通知订阅者,即调用订阅者的update函数
39         set<Observer_base*>::iterator it; 
40         for (it = followers.begin(); it != followers.end(); ++it) {
41             (*it)->update(this->words);
42         }
43         
44     }
45 };
46 
47 
48 // 观察者的一个实例,比如一个球迷 
49 class Observer_barcaFans :public Observer_base{
50 private:
51     string name;
52     string news;
53 
54 public:
55     // 构造函数
56     Observer_barcaFans(const string& name)
57     :name(name) {}
58 
59     // 更新消息
60     void update(const string& words){
61         this->news = words;
62         cout << "用户" << name << "你好! 巴萨的最新比分是: " << news << endl;
63     }
64 
65     // 获取球迷名字
66     const string get_name() const {
67         return this->name;
68     }
69 
70     // 运算符重载
71     bool operator == (const Observer_base* outer) const {
72         return outer->get_name() == this->name;
73     }
74 };
 1 int main() {
 2     // 创建一个比分推送 
 3     Target_base* scorePush_liu = new Target_scorePush();
 4 
 5     // 创建两个球迷 
 6     Observer_base* li_ming = new Observer_barcaFans("李明");
 7     Observer_base* xiao_hong = new Observer_barcaFans("小红");
 8 
 9     // 进行订阅 
10     scorePush_liu->add_one_follower(li_ming);
11     scorePush_liu->add_one_follower(xiao_hong);
12 
13     // 推送比分 
14     scorePush_liu->set_string("巴萨 1 : 0 马洛卡       \n特狮助攻,格子小角度挑射破门!\n");
15     scorePush_liu->set_string("巴萨 2 : 0 马洛卡       \n常规操作,梅西禁区外远射破门。\n");
16     scorePush_liu->set_string("巴萨 2 : 1 马洛卡       \n呵呵。\n");
17     scorePush_liu->set_string("巴萨 3 : 1 马洛卡       \n复制粘贴!梅西禁区外远射破门。\n");
18     scorePush_liu->set_string("巴萨 4 : 1 马洛卡       \n德容直塞,苏神脚跟画彩虹!巧射破门。\n");
19     scorePush_liu->set_string("巴萨 4 : 2 马洛卡       \n呵呵,还敢还手。\n");
20     scorePush_liu->set_string("巴萨 5 : 2 马洛卡       \n苏神回做,梅西搓射洞穿人墙,手捧金球头带帽!\n");
21     scorePush_liu->set_string("全场比赛结束,巴萨 5 : 2 马洛卡       \nps:巴尔韦德下课!\n");
22 
23 
24     delete scorePush_liu;
25     delete li_ming;
26     delete xiao_hong;
27 
28     return 0;
29 }

  代码的实现结果如下:

 
4,模式分析
  根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。 外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
   外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。 外观模式的目的在于降低系统的复杂程度。 外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。
  外观模式有如下优点:
  • 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
  • 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。

  同时,外观模式还有如下缺点:

  • 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

5,总结

  在外观模式中,外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。

  外观模式包含两个角色:外观角色是在客户端直接调用的角色,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理;在软件系统中可以同时有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能。

  外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。

  外观模式主要优点在于对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易,它实现了子系统与客户之间的松耦合关系,并降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程;其缺点在于不能很好地限制客户使用子系统类,而且在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。

  外观模式适用情况包括:要为一个复杂子系统提供一个简单接口;客户程序与多个子系统之间存在很大的依赖性;在层次化结构中,需要定义系统中每一层的入口,使得层与层之间不直接产生联系。

 

 

おすすめ

転載: www.cnblogs.com/imerliu/p/12004973.html