まず、テンプレートメソッドパターン
アルゴリズムのスケルトンを定義し、サブクラスが1つ以上のステップの実装を提供できるようにします
アプリケーション:
- アルゴリズムの定数部分を一度に実装し、変数の動作をサブクラスに任せる
- コードの重複を回避するために、各サブカテゴリの共通の動作が抽出され、共通の親クラスに集約されます
利点:
- 再利用性を向上させる
- スケーラビリティを向上させる
- 開閉の原則を満たします
短所:
- クラス数の増加
- システム実装の複雑さを増す
- 親クラスは新しい抽象メソッドを追加し、サブクラスも実装する必要があります
public abstract class ACourse {
protected final void makeCourse() {
this.makePPT();
this.makeVideo();
if (needWriteArticle()) {
this.writeArticle();
}
this.packageCourse();
}
final void makePPT() {
System.out.println("制作PPT");
}
final void makeVideo() {
System.out.println("制作视频");
}
final void writeArticle() {
System.out.println("编写手记");
}
// 钩子方法
protected boolean needWriteArticle() {
return false;
}
abstract void packageCourse();
}
public class FECourse extends ACourse {
private boolean needWriteArticleFlag = false;
@Override
void packageCourse() {
System.out.println("提供课程的前端代码");
System.out.println("提供课程的图片等多媒体素材");
}
public FECourse(boolean needWriteArticleFlag) {
this.needWriteArticleFlag = needWriteArticleFlag;
}
@Override
protected boolean needWriteArticle() {
return this.needWriteArticleFlag;
}
}
次に、イテレーターパターン
オブジェクトの内部表現を公開せずに、コレクションオブジェクトの各要素に順次アクセスする方法を提供する
アプリケーション:
- コレクションオブジェクトのコンテンツにアクセスする
- 異なるコレクション構造を横断するための統一されたインターフェースを提供する
利点:
- コレクションオブジェクトの走査動作を分離
短所:
- クラスの数はペアで増加します
// 集合类
public interface CourseAggregate {
void addCourse(Course course);
void removeCourse(Course course);
CourseIterator getCourseIterator();
}
public class CourseAggregateImpl implements CourseAggregate {
private List courseList;
public CourseAggregateImpl() {
this.courseList = new ArrayList();
}
// remove add
@Override
public CourseIterator getCourseIterator() {
return new CourseIteratorImpl(courseList);
}
}
// 迭代器
public interface CourseIterator {
Course nextCourse();
boolean isLastCourse();
}
public class CourseIteratorImpl implements CourseIterator {
private List courseList;
private int position;
private Course course;
public CourseIteratorImpl(List courseList) {
this.courseList = courseList;
}
@Override
public Course nextCourse() {
System.out.println("返回课程,位置是: " + position);
course = (Course) courseList.get(position);
position++;
return course;
}
@Override
public boolean isLastCourse() {
if (position < courseList.size()) {
return false;
}
return true;
}
}
3.戦略モード
アルゴリズムファミリーを定義し、個別にカプセル化し、相互に置き換えます。アルゴリズムの変更はユーザーに影響しません
アプリケーション:
- 多くのカテゴリがあり、唯一の違いは動作です
- システムは、いくつかのアルゴリズムの1つを動的に選択する必要があります
利点:
- 開閉の原則を満たします
- 複数の条件付き転送の使用を避ける
- アルゴリズムの機密性とセキュリティを向上させる
短所:
- クライアントはすべての戦略を知り、選択する必要があります
- 多くの戦略を生み出す
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void executePromotionStrategy() {
promotionStrategy.doPromotion();
}
}
// 策略
public interface PromotionStrategy {
void doPromotion();
}
public class ManJianPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("满减促销,满200-20元");
}
}
public class FanXianPromotionStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额存放到账户余额中");
}
}
第四に、通訳モード
言語を指定して、文法の表現を定義し、言語を解釈するためのインタープリターを定義します
アプリケーション:
- 特定の種類の問題が頻繁に発生する
利点:
- 文法は多くのクラスで表現され、拡張が簡単です
短所:
- 文法規則が多すぎる場合は、複雑さを増やします
V.オブザーバーモード
オブジェクト間の1対多の依存関係を定義します。複数のオブザーバーが特定のテーマオブジェクトを同時にリッスンします。テーマが変更されると、すべてのオブザーバーが通知を受け取ります
アプリケーション:
- 行動シナリオを関連付け、トリガーメカニズムを確立する
利点:
- オブザーバーとオブザーバーの間に抽象的なカップリングを確立する
- 放送通信
短所:
- オブザーバー間の詳細依存が多すぎるため、時間の消費とプログラムの複雑さが増す
- ループ呼び出しを避ける
// 主题
public class Subject {
// 观察者数组
private Vector<Observer> oVector = new Vector<>();
public void addObserver(Observer observer) {
this.oVector.add(observer);
}
public void deleteObserver(Observer observer) {
this.oVector.remove(observer);
}
public void notifyObserver() {
for (Observer observer : this.oVector) {
observer.update();
}
}
}
public class ConcreteSubject extends Subject {
// 具体业务
public void doSomething() {
// ...
super.notifyObserver();
}
}
// 观察者
public interface Observer {
public void update();
}
public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("收到消息,进行处理");
}
}
6.メモモード
オブジェクトの状態を保存して、後で復元できるようにする
アプリケーション:
- データの保存と復元
- 以前の状態に戻したい
利点:
- 回復可能なメカニズムを提供する
- アーカイブ情報パッケージ
短所:
- 資源占有
// 可以创建备忘录和恢复的普通对象
public class Originator {
private String state;
public Memento createMemento() {
return new Memento(state);
}
public void restore(Memento memento) {
this.state = memento.getState();
}
}
// 备忘录
public class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
// 备忘录管理者
public class Caretaker {
private Memento memento;
public Memento restoreMemento() {
return memento;
}
public void storeMemengto(Memento memento) {
this.memento = memento;
}
}
7、コマンドモード
リクエストをオブジェクトにカプセル化して、さまざまなリクエストを使用できるようにする
アプリケーション内のオブジェクトの責任と通信方法を解決する
アプリケーション:
- 要求発信者と要求受信者の分離
- 実行待ちの動作を抽象化する必要がある
利点:
- カップリングを減らす
- 新しいコマンドまたはコマンドのグループを簡単に拡張
短所:
- クラスの数を増やし、システムの複雑さを増やす
// 命令
interface Command {
void execute();
}
class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
class LightOffCommand implements Command {
Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.off();
}
}
// 命令接受者
class Light {
public void on() {
System.out.println("打开电灯。。。");
}
public void off() {
System.out.println("关闭电灯。。。");
}
}
8つの中間モデル
オブジェクトのグループがどのように相互作用するかをカプセル化するオブジェクトを定義する
アプリケーション:
- システム内のオブジェクト間に複雑な参照関係があり、無秩序な相互依存構造になります
- インタラクティブな公開動作、動作を変更する必要がある場合は、新しい中間クラスを追加できます
利点:
- 1対多を1対1に変換する
- クラス間の分離
短所:
- 仲介者が多すぎてシステムが複雑になる
abstract class Colleague {
public abstract void onEvent(Mediator mediator);
}
class Alarm extends Colleague {
@Override
public void onEvent(Mediator mediator) {
mediator.doEvent("alarm");
}
public void doAlarm() {
System.out.println("doAlarm()");
}
}
// 中介者
abstract class Mediator {
public abstract void doEvent(String eventType);
}
class ConcreteMediator extends Mediator {
private Alarm alarm;
public ConcreteMediator(Alarm alarm) {
this.alarm = alarm;
}
@Override
public void doEvent(String eventType) {
switch (eventType) {
case "alarm":
break;
}
}
}
9.責任の連鎖モデル
2番目のリクエストオブジェクトを受け入れるリクエストのチェーンを作成する
アプリケーション:
- リクエストの処理には、複数のオブジェクトの1つ以上の協力が必要です
利点:
- リクエストの送信者と受信者を分離する
- 責任チェーンは動的に組み合わせることができます
短所:
- 責任の長い連鎖がパフォーマンスに影響する
- 責任の連鎖が多すぎる可能性があります
interface ILeave {
String getName();
int getNum();
String getContent();
}
abstract class Handler {
protected Handler successor;
public Handler(Handler successor) {
this.successor = successor;
}
abstract void handleLeave(ILeave leave);
}
class GroupLeader extends Handler {
public GroupLeader(Handler successor) {
super(successor);
}
@Override
public void handleLeave(ILeave leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("小组长审批:同意。");
if (successor != null) {
successor.handleLeave(leave);
}
}
}
class Manager extends Handler {
public Manager(Handler successor) {
super(successor);
}
@Override
public void handleLeave(ILeave leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("部门经理审批:同意。");
}
}
テン、ビジターモード
データ構造の要素に対する操作をカプセル化する
各要素のクラスを変更せずに、これらの要素に作用する操作を定義できます
アプリケーション:
- データ構造には多くのタイプのオブジェクトが含まれています
- データ構造とデータ操作の分離
利点:
- 新しい操作の追加は簡単です
短所:
- 新しいデータ構造の追加の難しさ
- 特定の要素の変更が面倒
public interface ComputerPart {
public void accept(ComputerPartVisitor computerPartVisitor);
}
public class Computer implements ComputerPart {
ComputerPart[] parts;
public Computer() {
parts = new ComputerPart[] { new Mouse(), new Keyboard() };
}
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
for (int i = 0; i < parts.length; i++) {
parts[i].accept(computerPartVisitor);
}
computerPartVisitor.visit(this);
}
}
public class Keyboard implements ComputerPart {
@Override
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Mouse implements ComputerPart {
// accept
}
public interface ComputerPartVisitor {
public void visit(Mouse mouse);
public void visit(Keyboard keyboard);
public void visit(Computer computer);
}
public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
// ...
}
public class Test {
public static void main(String[] args) {
ComputerPart computer = new Computer();
computer.accept(new ComputerPartDisplayVisitor());
}
}
11.状態モード
内部状態が変化したときにオブジェクトの動作を変更できるようにする
状態遷移図
アプリケーション:
- オブジェクトは複数の状態で存在し、相互に変換できます
利点:
- 異なる状態を分離する
- 相互依存を減らすために、状態遷移ロジックをStateサブクラスに分散します。
- 新しいステータスの追加は簡単です
短所:
- 多数の州が存在するビジネスシナリオは、クラス数の増加につながり、システムは複雑になります
interface State {
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
}
class HasQuarterState implements State {
private GumballMachine gumballMachine;
public HasQuarterState(GumballMachine gumballMachine) {
this.gumballMachine = gumballMachine;
}
@Override
public void insertQuarter() {
System.out.println("You can't insert another quarter");
}
@Override
public void ejectQuarter() {
System.out.println("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
@Override
public void turnCrank() {
System.out.println("You turned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
@Override
public void dispense() {
System.out.println("No gumball dispensed");
}
}
class NoQuarterState implements State {
// ...
}
class SoldOutState implements State {
// ...
}
class SoldState implements State {
// ...
}
class GumballMachine {
private State soldOutState;
private State noQuarterState;
private State hasQuarterState;
private State soldState;
private State state;
private int count = 0;
public GumballMachine(int numberGumballs) {
count = numberGumballs;
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
if (numberGumballs > 0) {
state = noQuarterState;
} else {
state = soldOutState;
}
}
public void insertQuarter() {
state.insertQuarter();
}
public void ejectQuarter() {
state.ejectQuarter();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
public void setState(State state) {
this.state = state;
}
public void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count -= 1;
}
}
// getter ...
}