- รูปแบบการออกแบบคืออะไร?
- คุณรู้รูปแบบการออกแบบอะไรบ้าง?
- บอกเราเกี่ยวกับรูปแบบซิงเกิลตันหน่อยสิ? จะทำให้เธรดปลอดภัยได้อย่างไร?
- บอกเราเกี่ยวกับรูปแบบโรงงาน?
- บอกเราเกี่ยวกับรูปแบบ AbstractFactory
- ช่วยเล่าให้เราฟังเกี่ยวกับรูปแบบ Adaper ที่แตกต่างจาก Wrapper หน่อยได้ไหม
- บอกเราเกี่ยวกับรูปแบบพร็อกซี
- ตัววนซ้ำคืออะไร? คุณรู้จักอินเทอร์เฟซใดบ้างที่เกี่ยวข้องกับตัววนซ้ำ
- ทำไมเราถึงต้องการคลาส Arrays?
- เหตุใดเราจึงต้องมีคลาส Collections
-
รูปแบบการออกแบบเป็นวิธีแก้ปัญหาที่ประสบความสำเร็จและเป็นที่ยอมรับสำหรับปัญหาทั่วไปส่วนใหญ่ที่เกิดขึ้นระหว่างการออกแบบและพัฒนาโปรแกรมหรือชิ้นส่วน
-
Singleton
,Factory
,Abstract Factory
,Template method
,Strategy
,Pool
,Adapter
,Proxy
,Bridge
,MVC
. -
เมื่อคุณต้องการเพียงอินสแตนซ์เดียวของคลาสที่มีอยู่ในโปรแกรม รูปแบบจะถูก
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
ว่า ตามรูปแบบนี้ ออบเจ็กต์ที่แตกต่างกันจะถูกสร้างขึ้นในวิธีเดียว ขึ้นอยู่กับข้อมูลอินพุตขาเข้า (ค่าพารามิเตอร์) ออบเจ็กต์ทั้งหมดเหล่านี้ต้องมีบรรพบุรุษร่วมกัน (หรืออินเทอร์เฟซที่นำไปใช้ได้ทั่วไป) ดูเหมือนว่านี้: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
เป็นคลาสยูทิลิตี้สำหรับการทำงานกับคอลเลกชัน คลาสนี้มีวิธีการเพิ่มองค์ประกอบในคอลเลกชัน การเติมองค์ประกอบในคอลเลกชัน ค้นหาคอลเลกชัน การคัดลอกคอลเลกชัน การเปรียบเทียบคอลเลกชัน การค้นหาองค์ประกอบสูงสุดและต่ำสุดของคอลเลกชัน ตลอดจนวิธีการรับการแก้ไขเฉพาะคอลเลกชันของ ประเภทที่รู้จัก (เช่น คุณสามารถรับคอลเล็กชันแบบปลอดภัยสำหรับเธรดหรือคอลเล็กชันที่ไม่เปลี่ยนรูปที่มีองค์ประกอบเดียว)
GO TO FULL VERSION