この記事では、会社の階層構造図の問題を解決するための訪問者モードの使用について説明します。次のように、参照のために共有してください。
1。パターン定義
ビジターモード:オブジェクト構造の各要素に作用する操作を表します。これにより、ユーザーは、各要素のクラスを変更せずに、これらの要素に作用する新しい操作を定義できます。
2。モデルの例
1パターン分析
このモデルを説明するために、会社の階層を借ります。
2 Visitor Mode静的クラス図
3つのコードの例
3.1要約スタッフ
パッケージcom.demo.Structure; Import com.demo.visitor.ivisitor;/** * abstract Employee class * * @author * */public Abstractクラススタッフ{//従業員番号保護された文字列no; //従業員名保護された文字列名。 //保護された文字列位置の位置。 //給与保護されたフロート給与。 //プライベートプロパティの長さの文字列プライベートインター。 //構築方法パブリックスタッフ(文字列番号、文字列名、文字列位置、フロート給与){this.no = no; this.name = name; this.position = position; this.salary = salary; //合計バイトの長さthis.length +=(no == null || "" .equals(no.trim()))? 0:no.getBytes()。長さ; this.length +=(name == null || "" .equals(name.trim())? 0:position.getBytes()。長さ; this.length +=(position == null || "" .equals(position.trim())? 0:position.getBytes()。長さ; this.length += string.valueof(salary).getBytes()。length; } //基本的なユーザー情報を取得しますprintuserbaseinfo(){system.out.println( " - |" + this.no + "" + this.name + "" + this.position + "" + this.salary); } //従業員情報の追加パブリックアブストラクトvoid add(スタッフスタッフ); //従業員のパブリック抽象スタッフを削除する(文字列番号); //訪問者オブジェクトを受け取るパブリックアブストラクトボイドaccept(Ivisitor Visitor); public string getno(){return no; } public void setno(string no){this.no = no; } public string getname(){return name; } public void setName(string name){this.name = name; } public string getPosition(){return position; } public void setposition(string position){this.position = position; } public float getSalary(){return Salary; } public void setSalary(float Salary){this.salary = salary; }}3.2マネージャー
パッケージcom.demo.structure; Import java.util.arraylist; Import com.demo.visitor.ivisitor;/** * Manager(指揮下にある他の従業員を持つ人) * * @author * */public class Manager {//従業員に関する情報を保存プライベート最終配列<スタッフ<スタッフ> Arraylist = new Arraylist <stuff>); //構築方法パブリックマネージャー(文字列番号、文字列名、文字列位、フロート給与){super(no、name、position、salary); } / ***従業員を追加* / @Override public void add(スタッフスタッフ){this.arraylist.add(stuff); } / ***従業員情報を削除* / @Overrideパブリックスタッフremove(string no){スタッフスタッフ= null; if(no!= null &&! ""。equals(no.trim())){for(int i = 0; i <this.arraylist.size(); i ++){if(this.arraylist.get(i)== null){続行; } if(no.equals(this.arraylist.get(i).getno())){stuff = this.arraylist.remove(i);壊す; }}}スタッフを返します。 } //訪問者オブジェクトを受信@Override public void Accept(Ivisitor Visitor){// Your Own Visitor.visit(this); //リストリストでさまざまな要素オブジェクトをトラバースし、(int i = 0; i <this.arraylist.size(); i ++){if(this.arraylist.get(i)== null){continue; } //訪問者オブジェクトthis.arraylist.get(i).accept(visitor); }}}3.3普通の従業員
パッケージcom.demo.structure; Import com.demo.visitor.ivisitor;/** *普通の従業員(実在の従業員) * * @author * * */public class Employeesはスタッフを拡張します{//構成方法公開従業員(文字列、文字列名、ストリングポジション、フロート給与){スーパー(ノー、名前、ポジション、給与); } / ***従業員情報の追加* / @Override public void add(スタッフスタッフ){return; } / ***従業員情報を削除* / @Overrideパブリックスタッフremody(string no){// nullをnullに直接返します。 } //訪問者オブジェクトを受信しますpublic void Accept(ivisitor visitor){visitor.visit(this); }}3.4 Visitor Interface-Ivisitor
パッケージcom.demo.visitor; Import com.demo.structure.employees; Import com.demo.structure.manager;/** * visitor interface * * @author * */public interface ivisitor {// Access Manager public void visit(Manager Manager); //普通の従業員にアクセスする公的な訪問(従業員の従業員);}3.5従業員の基本情報訪問者PrintBaseInFovistor
パッケージcom.demo.visitor; Import com.demo.structure.employees; Import com.demo.structure.manager;/***基本情報訪問者** @author**/public class printbaseinfovisitorを実装しますivisitor {/***アクセスマネージャーオブジェクト*/パブリックボイズマネージャー:マネージャーマネージャー: manager.printuserbaseinfo(); } / ***通常の従業員オブジェクトにアクセス* / public void visit(従業員従業員){System.out.print( " - 一般従業員:"); employes.printuserbaseinfo(); }}3.6従業員の給与を述べるための訪問者インターフェイスを作成 - isalaryvistor
パッケージcom.demo.visitor;/** *給与訪問者の計算 * * @author * * */public interface isalaryvisitor extends ivisitor {// Statistics Manager Salary Public Printmanagertotalsalary(); //統計一般従業員の給与公開void printemployeStotalsalary(); //統計すべての従業員給与公開void printtotalsalary();}3.7従業員の給与と訪問者の統計は、サラリーベイスターを実現します
パッケージcom.demo.visitor; Import com.demo.structure.employees; Import com.demo.structure.manager;/** *給与訪問者 * * @author * * */public class salaryvisitorの計算の具体的な実装{//合計マネージャーの給与マネージャーマネージャー。 //普通の従業員の総給与民間のフロート雇用者。 public SalaryVisitor(){ManagerSalary = 0; employeessalary = 0; } // Access Manager public void Visit(Manager Manager){ManagerSalary += Manager.getSalary(); } //訪問普通の従業員の公開void訪問(従業員の従業員){employeessalary += employees.getSalary(); } //統計一般従業員の給与公開void printemployeestotalsalary(){system.out.println( "一般従業員の給与額:" + employeSsalary); } //統計マネージャーの給与パブリックvoid printmanagertotalsalary(){system.out.println( "マネージャー給与額:" +マネージャーラリー); } //すべての従業員salaryの統計printtotalsalary(){system.out.println( "雇用主の給与:" +(managersalarary + employeSsalary)); }}3.8クライアントテストクライアント
パッケージcom.demo; import com.demo.structure.employees; import com.demo.structure.manager; import com.demo.structure.staff; Import com.demo.visitor.printbaseinfovisitor; Import com.demo.visitor.salaryvisitor; args */ public static void main(string [] args){//会社CEOスタッフボス= new Manager( "1"、 "Big Boss"、 "CEO"、100000); / *** CEOには複数の部門マネージャーがいます*/ //財務部門マネージャースタッフファイナンスマネーガー=新しいマネージャー( "11"、 "Zhang"、 "Finance Manager"、60000); //人事部門マネージャースタッフ担当者Manager = new Manager( "12"、 "大統領Wang"、「社長マネージャー」、60000); //技術部門マネージャースタッフTechnicalManager = new Manager( "13"、 "President Chen"、 "Technical Department Manager"、60000); / ***技術部門にはアシスタントと数人の監督者もいます*/ //技術部門アシスタントスタッフDeptassistant = new Manager( "1301"、 "Assistant Wang"、 "Department Assistant"、20000); //技術部門ディレクター1スタッフDeptmanager1 = new Manager( "1302"、 "Supervisor1"、 "Technical Director"、30000); / ** *テクニカルディレクターDeptmanager1ソフトウェアエンジニア(最終的に働く人)がいます */スタッフSoftwareEngineer1 =新しい従業員( "1302001"、 "Zhang San"、 "Software Engineer"、5000);スタッフSoftwareEngineer2 =新しい従業員( "1302002"、 "li si"、 "ソフトウェアエンジニア"、5500);スタッフSoftwareEngineer3 =新しい従業員( "1302003"、 "Wang Wu"、 "Software Engineer"、4500); //テクニカルスーパーバイザーの従業員情報を追加1.Deptmanager1.Add(SoftwareEngineer1); deptmanager1.add(softwareengineer2); deptmanager1.add(softwareengineer3); //技術部門ディレクター2スタッフDeptmanager2 = new Manager( "1303"、 "Supervisor2"、 "Technical Director"、30000); //追加:部門アシスタント、テクニカルディレクター1、およびテクニカルディレクター2 TechnicalManager.Add(Deptassistant); TechnicalManager.Add(deptmanager1); TechnicalManager.Add(deptmanager2); //マーケティングマネージャースタッフMarketingManager = new Manager( "14"、 "Mr. Wu"、 "Market Manager"、60000); // CEOに追加:財務部門マネージャー、人事部門マネージャー、技術部門マネージャー、マーケティングマネージャーBoss.Add(FinanceManager); boss.add(personthermanager); Boss.Add(TechnicalManager); Boss.Add(MarketingManager); // CEO情報を印刷// BOSS.PRINTUSERBASEINFO(); // CEOの従業員情報Boss.accept(new PrintBaseInFovisitor())を印刷します。 / ***統計従業員の給与*/ //統計を作成する従業員給与訪問者給与訪問者訪問者= new SalaryVisitor(); //訪問者のボスを受け入れさせます。 //マネージャーの給与統計訪問者。printmanagertotalsalary(); //一般的な従業員給与統計訪問者。PrintemployeSeStotalSalary(); //すべての従業員給与統計訪問者。printtotalSalary(); }}4ランニング結果
- マネージャー: - | 1ビッグボスCEO 100000.0
- マネージャー: - | 11 Zhang Finance Department Manager 60000.0
- マネージャー: - | 12一般的な人事部マネージャー60000.0
- マネージャー: - | 13一般チェン技術部門マネージャー60000.0
- マネージャー: - | 1301アシスタントワン部門アシスタント20000.0
- マネージャー: - | 1302スーパーバイザー1テクニカルスーパーバイザー30000.0
- 一般従業員: - | 1302001 Zhang Sanソフトウェアエンジニア5000.0
- 一般従業員: - | 1302002 Li Siソフトウェアエンジニア5500.0
- 一般従業員: - | 1302003 Wang Wu Software Engineer 4500.0
- マネージャー: - | 1303スーパーバイザー2テクニカルスーパーバイザー30000.0
- マネージャー: - | 14ゼネラルマネージャーWUマーケティング部門60000.0
総マネージャー給与:420,000.0
一般従業員の総給与:15000.0
従業員の総給与:435,000.0
iii。このパターンの設計原則
1「オープンクローズ」原則
2単一責任の原則
4.機会を使用します
1オブジェクト構造にさまざまな種類のオブジェクトを含めると、異なるインターフェイスがあり、これらの異なるオブジェクトの特定のクラスに依存する操作を実装する必要があります。
2オブジェクト構造内のオブジェクトで多くの異なる関係のない操作を実行する必要があります。これらの操作をこれらのオブジェクトのクラスに関連付けることを避けたいです。 Visitor Modeを使用すると、関連操作をクラスで個別に集中および定義できます。
3このオブジェクト構造が多くのアプリケーションで共有されている場合、Visitorモードを使用して、各アプリケーションが使用する必要がある操作のみを含めることができます。
4オブジェクト構造を定義するクラスはめったに変更されませんが、この構造で定義するには新しい操作が必要です。
5。訪問者モード静的クラス図
Java関連のコンテンツについては、このサイトに興味のある読者は、「Javaデータ構造とアルゴリズムのチュートリアル」、「Java操作DOMノードのヒントの概要」、「Javaファイルの要約およびディレクトリ操作のヒント」、「Java Cache操作のヒントの要約」というトピックを見ることができます。
この記事がみんなのJavaプログラミングに役立つことを願っています。