デザインパターンは、特定の事業と組み合わせて、理論的には放置しないでください、それはより多くの香り〜となります
1.はじめに
どのように多くの設計パターン我々はいくつか理解しているが、多くの場合にも、それが何であるかを知りませんでした。
実際のビジネスシナリオでは、よりエレガントなコードを書くために任意のデザインパターンを使用していますか?
私たちはそこに新しいプロダクトマネージャーからより多くの需要を受けた日の後に、シャトルは、SQLプログラミングに直面して、MVCを開始しました。
私たちは、MVCアーキテクチャを使用することに慣れている、リアルタイムでは貧血オブジェクトモデルの多くを作成し、手続き型のコードを記述することは非常に簡単です。私たちは何の論理的な動作がないことを、オブジェクト、多くの場合、単にデータキャリアを使用しています。当社の設計プロセスが、また、ER図、データ駆動型デザインセンターから開始します。DAO、日CRUDの翌日にサービスコントローラから需要へのインタフェース。
どのようなデザインパターン?それは存在しません!
今日、我々はシーンを落ちることがCRUDにコモンモード(工場出荷時のモード、プロキシモード、テンプレートモード)を設計しようと、私たちはいくつかのインスピレーションをもたらすことを願って。
デザインパターンの2理解
デザインパターン(デザインパターン)、要約が得られた後でない前任者の想像力の案出が、ソフトウェア設計プロセスの長期実際には、。
コードパターンを作るために設計を使用して、スケーラブル、高重合低い結合特性です。
世界は何のデザインパターンを持っていないだろう、より多くの人々は、いくつかのデザインパターンがあるでしょう、コードを記述します。
オブジェクト指向のデザインパターンは、7つの基本的な原則があります。
-
オープンクローズドの原則(第一原理):拡張のために開くには、修正のため閉鎖
-
単一責任の原則:単一のクラスの責任を達成するために
-
リヒター置換原則は:継承システムを破壊しないでください。
-
依存関係逆転の原則:指向プログラミング・インタフェース
-
インタフェース棲み分け原理:デザインは、単一の合理化へのインタフェース
-
合成ポリマー/多重化の原則:達成するために第二に、継承の使用を検討する前に、使用前に達成しようとするか、ポリマー組成物
-
デメテルの法則の原則のまたは少なくとも知識:削減カップリング
過去には、我々は理論、今日の学習のモードを設計するために行くだろう、我々はCRUDシーンを落ちることがあり、コモンモード(工場出荷時のモード、プロキシモード、テンプレートモード)を設計しようと、私たちはいくつかの本当のインスピレーションをもたらすことを願って。
3.実際の例デザインパターン
3.1ファクトリパターン
1)はじめに工場パターン
Factoryパターンは、デザインパターンを持つ私たちが最も精通している必要があり、およびフレームワークは、xxxFactory.createしてオブジェクトを取得するには、古典的なxxxxFactoryがたくさんあります。ここでは、工場のおなじみのパターンのクラス図がアップ思い出すことができるはず与えて、詳細を続行しません。
工場出荷時のパターンの利点は明らかです。
- 呼び出し側は、オブジェクトを作成するだけで、その上にその名前を知りたいです。
- 高いスケーラビリティ、あなたがすることができファクトリクラスの拡張限り、製品を追加したい場合。
- シールド製品の具体的な実現は、呼び出し側は、唯一の製品のインターフェースに関する。
だから、どのように実際のビジネス展開地面のそれを使用するには?
例えば2)の要求
我々は、MySQLのNavicatまたは作業台に似たHBaseの管理システムを、行う必要があります。
だから、非常に重要なモジュールで変更して再検索のHBaseに追加や削除を実現することです。
オープンソースHBaseのクライアントは、我々はシステムに統合しますどのように、標準のCRUDのAPIを提供してきましたか?
3)簡単なコード
@RestController("/hbase/execute")
public class DemoController {
private HBaseExecuteService hbaseExecuteService;
public DemoController(ExecuteService executeService) {
this.hbaseExecuteService = executeService;
}
@PostMapping("/insert")
public void insertDate(InsertCondition insertCondition) {
hbaseExecuteService.insertDate(insertCondition);
}
@PostMapping("/update")
public void updateDate(UpdateCondition updateCondition) {
hbaseExecuteService.updateDate(updateCondition;
}
@PostMapping("/delete")
public void deleteDate(DeleteCondition deleteCondition) {
hbaseExecuteService.deleteData(deleteCondition);
}
@GetMapping("/select")
public Object selectDate(SelectCondition selectCondition) {
return hbaseExecuteService.seletData(selectCondition);
}
}
機能の増分は、あなたが同様の操作にサービスを提供するために、コントローラから再びそれを記述する必要があります。
DTOはまた、テーブル名、カラム名やその他の検索条件などの変数の重複の多くをもたらすでしょう、関連するデータ転送の多くを構築する必要があります。
4)モードアプリケーション
抽象インタフェース
public interface HBaseCommand {
/**
* 执行命令
*/
ExecResult execute();
}
公開抽象クラスには、コンフィギュレーションを実装します
public class AbstractHBaseCommand implements HBaseCommand {
Configuration configuration;
AbstractHBaseCommand(ExecuteCondition executeCondition) {
this.configuration = getConfiguration(executeCondition.getResourceId());
}
private Configuration getConfiguration(String resourceId) {
Configuration conf = HBaseConfiguration.create();
//做一些配置相关事情
//。。。。
return conf;
}
@Override
public ExecResult execute() {
return null;
}
}
コンクリートファクトリクラスの製造指図
public class CommandFactory {
private ExecuteCondition executeCondition;
public CommandFactory(ExecuteCondition executeCondition) {
this.executeCondition = executeCondition;
}
public HBaseCommand create() {
HBaseCommand hBaseCommand;
switch (ExecuteTypeEnum.getTypeForName(executeCondition.getQueryType())) {
case Get:
return new GetCommand(executeCondition);
case Put:
return new PutCommand(executeCondition);
case Delete:
return new DeleteCommand(executeCondition);
}
return null;
}
}
実行インターフェイス、コマンド実行複数のCRUD
public class ExecuteController {
private ExecuteService executeService;
public ExecuteController(ExecuteService executeService) {
this.executeService = executeService;
}
@GetMapping
public Object exec(ExecuteCondition executeCondition) {
ExecResult execResult = executeService.execute(executeCondition);
return transform(execResult);
}
}
特定のコマンドの実行を作成するためのサービスコール工場
@Service
public class ExecuteService {
public ExecResult execute(ExecuteCondition executeCondition) {
CommandFactory factory = new CommandFactory(executeCondition);
HBaseCommand command = factory.create();
return command.execute();
}
}
あなたは、新しいコマンドを追加するたびに、できるだけで新しい秩序関連クラスを実装する必要があります
3.2プロキシモード
1)モードの紹介
プロキシモードは、非常に身近なパターンです。
元のオブジェクトへのプロキシオブジェクト制御参照によってプロキシを提供することを目的とします。これは、ユーザが直接、実際の観客と通信することはできませんができます。
クライアントとターゲットオーディエンスとの間の仲介などのプロキシオブジェクトは、また、上記の程度を削減しながら、元のオブジェクトを拡張するいくつかの作業カット(プレイログ)を行い、元のオブジェクトの能力を制限する機能など、多くの役割を、再生することができますシステムのカップリング。
例えば2)の要求
いくつかのメソッドを実装するクライアントオブジェクトが既にあります。
今、2つの要件があります。
- 希望このオブジェクトのメソッドはサポートされなくなりました。
- この時にクライアントレコードの実行のすべてのメソッドを願っています。
3)簡単なコード
元のクラスを変更するには
- DELETEメソッドA(誰かが参照している場合、互換性のない変更は、エラーをコンパイルすることができます)
- それぞれの方法(多くのビジネスの侵略、コード、深刻な冗長性)の前と後の計算時間を埋め
4)モードアプリケーション
すでにサポートするための方法は、実際には、多くの方法は、相続または静的プロキシができ、そこにあります。
静的プロキシコード:
public class ConnectionProxy implements Connection {
private Connection connection;
public ConnectionProxy(Connection connection) {
this.connection = connection;
}
@Override
public Admin getAdmin() throws IOException {
//抛出一个异常
throw new UnsupportedOperationException();
}
@Override
public boolean isClosed() {
return connection.isClosed();
}
@Override
public void abort(String why, Throwable e) {
connection.abort(why, e);
}
}
各方法は、動的プロキシを達成するために使用することができる後に計算するための埋込。
public class TableProxy implements InvocationHandler {
private Object target;
public TableProxy(Object target) {
this.target = target;
}
/**
* 获取被代理接口实例对象
*
* @param <T>
* @return
*/
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long current = System.currentTimeMillis();
Object invoke;
try {
invoke = method.invoke(target, args);
} catch (Throwable throwable) {
throw throwable;
}
long cost = System.currentTimeMillis() - current;
System.out.println("cost time: " + cost);
return invoke;
}
}
3.3テンプレートメソッド
1)モードの紹介
プロセスフレームワークは、一つの操作を定義するが、サブクラスの処理遅延の特定のステップのいくつかは、実施します。
テンプレート法は、アルゴリズムの特定のステップを再定義することにより、カスタム動作を達成するためのフレームワークを変更することなく、このようなA処理をサブクラス。
もちろん、最も便利異なるサブクラスは、彼らがこのプロセスを完了するためのメソッドを実装する必要が正確に何を知っているのでという、我々は完璧なプロセスを保証することができるということです。
例えば2)の要求
実際には、テンプレートメソッドは、理解するのが最も簡単ですが、また非常に効率的。
クラステンプレートニーズの私達の最も一般的に使用される方法は、単一のワークフローの承認です。
私たちは今、作業オーダーの承認を達成するためのプロセスを定義する必要がある場合は具体的に、作業指示の作成、操作の承認、イベント実行、メッセージ通知プロセスを含む(実際には、プロセスはより複雑になることがあります)。
作業順序オブジェクトが非常に多く、サービス、データベースの変更要求、またはアクセス要求の兆候かもしれません。
3)簡単なコード
各作業指示プロセスは、コードの1セットを書き込みます。
- 努力とよりの複製。
- プロセスは、エグゼクティブのイベントが知らさ忘れ後などいくつかの重要な側面を、欠落していることができます。
4)モードアプリケーション
いくつかの方法を含むインタフェースを規定
public interface ChangeFlow {
void createOrder();
boolean approval();
boolean execute();
void notice();
}
プロセステンプレートには、完全なワークフローを実現するために様々な方法をステッチ
public class MainFlow {
public void mainFlow(ChangeFlow flow) {
flow.createOrder();
if (!flow.approval()){
System.out.println("抱歉,审批没有通过");
}
if (!flow.execute()) {
System.out.println("抱歉,执行失败");
}
flow.notice();
}
}
そこで、このような承認、予告通り、一般的な方法の内側AbstractChangeFlowで実装することができ、我々はすべて同じロジックです。
public class AbstractChangeFlow implements ChangeFlow {
@Override
public void createOrder() {
System.out.println("创建订单");
}
@Override
public boolean approval() {
if (xxx) {
System.out.println("审批通过");
return true;
}
return false;
}
@Override
public boolean execute() {
//交给其他子类自己复写
return true;
}
@Override
public void notice() {
System.out.println("notice");
}
}
最後に、ライン上DbFlow、主流量を達成するために、ライン上の特定の作業の順序()メソッドに応じてカスタムexcuteを実現しています。
4.まとめ
研究デザインパターン最も重要なことは、ドメインモデルの確立と合わせて、思考のデザインパターンの本質を理解するために、ビジネスシーンの理解、特定のビジネスシナリオでは、ビジネスの発展に考えておくことです。
あなたが学ぶか、デザインパターンについて話して、特定のビジネスシナリオから逸脱した場合、それは意味がありません。
一部の人々は、どのようにデザインパターンの間と上エンジニアリング、それを区別するために言いますか?
それは実際には非常に簡単です。
設計の初期段階では1)事業。プロパティは、ビジネスに精通している場合は、あなたには、いくつかのシンプルなデザインを行うことができ、繰り返しのビジネスの方向性を理解しています。
2)ビジネス反復プロセス。ビジネスニーズの調整であなたのコードは常に開閉の特定の原則でナイフ、デザインパターンの7つの原則の破壊を、変更すると、あなたはデザインパターンの使用について考えるべきです。
ここを参照してください、元は、簡単に関心のポイントではない、それのようなポイントは、あなたがより良い読みました -
知識残骸再ソート、ビルドのJavaの知識マップ:https://github.com/saigu/JavaKnowledgeGraph(歴史的なレビュー記事は非常に便利です)
I国民の関心番号「Aピル・ノート」、最新の更新プログラムのための初めてのスキャンコード。あなたが自由に大量の電子書籍のJavaテクノロジー・スタックを取得することができ、同時に、様々なメーカーが質問に直面しています。