- デザインパターンとは何ですか?
- どのようなデザインパターンを知っていますか?
- シングルトンパターンについて教えてください。スレッドセーフにする方法は?
- Factoryパターンについて教えてください。
- AbstractFactory パターンについて教えてください
- Adaper パターンと Wrapper との違いについて教えてください。
- Proxyパターンについて教えてください
- イテレータとは何ですか? イテレータに関連するインターフェイスをご存知ですか?
- なぜ Arrays クラスが必要なのでしょうか?
- Collections クラスが必要な理由は何ですか?
-
デザイン パターンは、プログラムまたはその一部の設計および開発中に発生する最も一般的な問題に対する、確立された成功した解決策です。
-
Singleton
、、、、、、、、、、。Factory
_ _ _ _ _ _ _ _Abstract Factory
Template method
Strategy
Pool
Adapter
Proxy
Bridge
MVC
-
プログラム内に存在するクラスのインスタンスが 1 つだけ必要な場合は、パターンが使用されます
Singleton
。次のようになります (遅延初期化)。clas Singleton { private Singleton instance; private Singleton() {} public static Singletot getInstance() { if (instance == null) instance = new Singleton(); return instance; } }
スレッドセーフにするために、メソッドに
getInstance()
修飾子を追加できますsynchronized
。ただし、これは最善の解決策ではありません (ただし、最も単純な解決策です)。より良い解決策は、getInstance
次のようにメソッドを記述することです (二重チェックされたロック)。public static synchronized Singleton getInstance() { if (instance == null) synchronized(Singleton.class) { instance = new Singleton(); } return instance; }
-
パターンは
Factory
生成パターンです。これにより、オンデマンド (たとえば、特定の条件下) でオブジェクトを作成できます。次のようになります。class Factory{ public static Object1 getObject1() { return new Object1(); } public static Object2 getObject2() { return new Object2(); } public static Object3 getObject3() { return new Object3(); } }
このパターンには、 と呼ばれるバリエーションもあります
FactoryMethod
。このパターンによれば、受信する入力データ (パラメーター値) に応じて、1 つのメソッドで異なるオブジェクトが作成されます。これらすべてのオブジェクトには、共通の祖先 (または共通の実装可能なインターフェイス) が必要です。次のようになります。class FactoryMethod { public enum TypeObject { TYPE1, TYPE2, TYPE3 } public static CommonClass getObject(TypeObject type) { switch(type) { case TYPE1: return new Object1(); case TYPE2: return new Object2(); case TYPE3: return new Object3(); default: return null; } } }
クラス
Object1
、Object2
およびObject3
クラスから継承しますCommonClass
。 -
パターンは
Abstract Factory
ジェネレーティブ デザイン パターンでもあります。このパターンに従って、複数の具体的なファクトリのテンプレートとして機能する抽象ファクトリが作成されます。以下に例を示します。class Human {} class Boy extends Human {} class TeenBoy extends Human {} class Man extends Human {} class OldMan extends Human {} class Girl extends Human {} class TeenGirl extends Human {} class Woman extends Human {} class OldWoman extends Human {} interface AbstractFactory { Human getPerson(int age); } class FactoryMale implements AbstractFactory { public Human getPerson(int age) { if (age < 12) return new Boy(); if (age >= 12 && age <= 20) return new TeenBoy(); if (age > 20 && age < 60) return new Man(); return new OldMan(); } } сlass FactoryFemale implements AbstractFactory { public Human getPerson(int age) { if (age < 12) return new Girl(); if (age >= 12 && age <= 20) return new TeenGirl(); if (age > 20 && age < 60) return new Woman(); return new OldWoman(); } }
-
パターンとは
Adapter
構造的なパターンのことです。その実装により、ある型のオブジェクトを、別の型のオブジェクト (通常は抽象型) が必要な場合に使用できるようになります。このパターンの実装例:interface TotalTime { int getTotalSeconds(); } interface Time { int getHours(); int getMinutes(); int getSeconds(); } class TimeAdapter extends TotalTime { private Time time; public TimeAdapter(Time time) { this.time = time; } public int getTotalTime() { return time.getSeconds + time.getMinutes * 60 + time.getHours * 60 * 60; } } class TotalTimeAdapter extends Time { private TotalTime totalTime; public TotalTimeAdapter(TotalTime totalTime) { this.totalTime = totalTime; } public int getSeconds() { return totalTime % 60; } public int getMinutes() { return (totalTime / 60) % 60; } public int getHours() { return totaltime/ (60 * 60) ; } } class Main { public static void main(String[] args) { Time time = new Time() { public int getSeconds() { return LocalTime.now().getSecond(); } public int getMinutes() { return LocalTime.now().getMinute(); } public int getHours() { return LocalTime.now().getHour() ; } }; TotalTime totalTime = new TimeAdapter(time); System.out.println(totalTime.getTotalSeconds()); TotalTime totalTime2 = new TotalTime() { public int getTotalSeconds() { LocalTime currTime = LocalTime.now(); return currTime.getSecond() + currTime.getMinute * 60 + currTime.getHour * 60 * 60; } }; Time time2 = new TotalTimeAdapter(totalTime2); System.out.println(time2.getHours + ":" + time2.getMinutes() + ":" + time2.getSeconds()); } }
При реализации паттерна
Wrapper
создаётся класс, который оборачивает исходный класс и реализует тот же интерфейс, который реализует исходный класс. Таким образом, это позволяет расширить функциональность исходного класса и использовать новый класс там, где ожидается использование исходного класса. Это отличается от реализации паттернаAdapter
тем, что в данном случае используется один интерфейс (тот же, что есть у исходного класса). В паттернеAdapter
же используется два интерфейса, и класс, который оборачивает экземпяр исходного класса, реализует совсем другой инферфейс, не интерфейс исходного класса. -
Паттерн
Proxy
— это структурный паттерн проектирования. Он нужен для того, чтобы контролировать доступ к Howому-то an objectу. Для этого пишется класс по типу "обёртка", то есть внутрь класса передаётся исходный an object, реализующий некий интерфейс, сам класс тоже реализует этот интерфейс, и в каждом методе этого класса вызывается похожий метод у исходного an object. Реализация того же интерфейса, что и у исходного an object, позволяет подменить исходный an object прокси-an objectом. Также это позволяет, не меняя исходного an object, "навешивать" на его методы Howую-то специальную дополнительную функциональность (например, логирование, проверка прав доступа, кэширование и т.д.). Пример:interface Bank { void setUserMoney(User user, double money); double getUserMoney(User user); } class CitiBank implements Bank { //оригинальный класс public void setUserMoney(User user, double money) { UserDAO.update(user,money); } public double getUserMoney(User user) { UserDAO.getUserMoney(user); } } class SecurityProxyBank implements Bank { private Bank bank; public SecurityProxyBank(Bank bank) { this.bank = bank; } public void setUserMoney(User user, double money) { if (!SecurityManager.authorize(user,BankAccounts.Manager) throw new SecurityException("User can't change money value"); UserDAO.update(user,money); } public double getUserMoney(User user) { if (!SecurityManager.authorize(user,BankAccounts.Manager) throw new SecurityException("User can't get money value"); UserDAO.getUserMoney(user); }
-
Итератор — это специальный внутренний an object коллекции, который позволяет последовательно перебирать элементы этой коллекций. Этот an object должен реализовывать интерфейс
Iterator<E>
, либоListIterator<E>
(для списков). Также, для того, чтобы перебирать элементы коллекции, коллекция должна поддерживать интерфейсIterable<E>
. ИнтерфейсIterable<E>
содержит всего один метод —iterator()
, который позволяет извне получить доступ к итератору коллекции.Интерфейс
Iterator<E>
содержит следующие методы:-
boolean hasNext()
— проверяет, есть ли в коллекции ещё Howой-то элемент -
E next()
— позволяет получить очередной элемент коллекции (после получения element, внутренний курсор итератора передвигается на следующий элемент коллекции) -
void remove()
— удаляет текущий элемент из коллекции
Интерфейс же
ListIterator<E>
содержит такие методы:-
boolean hasNext()
— проверяет, существуют ли ещё один элемент в коллекции (следующий за текущим) -
E next()
— возвращает очередной элемент коллекции (и передвигает внутренний курсок итератора на следующий элемент) -
int nextIndex()
— возвращает индекс следующего element -
void set(E e)
— устанавливает meaning текущего elementvoid add(E e)
. Добавляет элемент в конец списка. -
boolean hasPrevious()
— проверяет, существует ли Howой-то элемент в коллекции перед данным элементом -
E previous()
— возвращает текущий элемент коллекции и переводит курсор на предыдущий элемент коллекции -
int previousIndex
— возвращает индекс предыдущего element коллекции -
void remove()
— удаляет текущий элемент коллекции -
void add(E e)
— добавляет элемент e после текущего element коллекции
-
-
このクラスは、
Arrays
さまざまな配列操作用に設計されたユーティリティ クラスです。このクラスには、配列をリストに変換する、配列を検索する、配列をコピーする、配列を比較する、配列のハッシュコードを取得する、配列を文字列として表現するなどのメソッドがあります。 -
このクラスは、
Collections
コレクションを操作するためのユーティリティ クラスです。このクラスには、コレクションへの要素の追加、コレクションへの要素の入力、コレクションの検索、コレクションのコピー、コレクションの比較、コレクションの最大要素と最小要素の検索を行うためのメソッドに加え、コレクションの特定の変更を取得するためのメソッドがあります。既知の型 (たとえば、スレッドセーフなコレクションまたは 1 つの要素を含む不変のコレクションを取得できます)。
GO TO FULL VERSION