ЛЕКЦ 02: ДИЗАЙН ПАТТЕРНУУД (Design Patterns)
Хичээлийн зорилго: Програм хангамжийн бүтээлтэд байнга давтагддаг асуудлуудыг шийдвэрлэх батлагдсан загваруудыг (design patterns) ойлгож, Java хэл дээр хэрэгжүүлэх чадвар эзэмших.
ХЭСЭГ 1: ҮНДСЭН ОЙЛГОЛТ БА ОНОЛ (Theory & Foundations)
1.1 Дизайн паттерн гэж юу вэ? (What is a Design Pattern?)
Тодорхойлолт
Дизайн паттерн (Design Pattern) гэдэг нь програм хангамжийн дизайнд байнга давтагддаг асуудлыг шийдвэрлэх батлагдсан загвар юм.
Gang of Four (GoF) номноос: "Дизайн паттерн гэдэг нь тодорхой контекст дэх ерөнхий дизайны асуудлыг шийдвэрлэхэд зориулсан, хоорондоо харилцах объект, классуудын тодорхойлолт юм."
Түүхэн мэдээлэл
Дизайн паттерн гэдэг ойлголт нь анх Кристофер Александер (Christopher Alexander) гэдэг архитекторын 1977 оны "A Pattern Language: Towns, Buildings, Construction" номноос үүдэлтэй. Тэрээр барилга, хот байгуулалтад байнга давтагддаг асуудлуудыг шийдвэрлэх загваруудыг баримтжуулсан.
1995 онд Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides нар Александерийн санааг програм хангамжийн ертөнцөд авчирч "Design Patterns: Elements of Reusable Object-Oriented Software" номыг хэвлэсэн. Энэ 4 зохиогчийг "Gang of Four" (GoF) буюу "Дөрвөн хүний бүлэг" гэж нэрлэдэг.
Амьдрал дээрх зүйрлэл
Зүйрлэл 1 — Хоолны жор: Тогооч хоол бүрийг эхнээс нь зохион бодохгүй. Үүний оронд батлагдсан жор ашигладаг. Жор нь "ямар асуудлыг (юу хоол хийх), ямар орцоор, ямар дарааллаар шийдвэрлэх" гэдгийг тодорхойлдог. Дизайн паттерн ч яг ийм — програмчлалын "жор".
Зүйрлэл 2 — Барилгын зураг төсөл: Архитектор байшин бүрийг тэг-ээс зохиохгүй. "3 өрөө байр", "гал тогооны стандарт зохион байгуулалт" гэх мэт батлагдсан загварууд байдаг. Дизайн паттерн нь програмын "архитектурын загвар" юм.
Паттерн яагаад чухал вэ?
- Батлагдсан шийдэл — Олон жилийн туршлагаар шалгагдсан, алдаа бага
- Нийтлэг хэл — Хөгжүүлэгчид хоорондоо "Энд Singleton хэрэглэ" гэхэд бүгд ойлгоно
- Дахин ашиглалт — Нэг удаа сурч, олон удаа ашиглана
- Код уншигдахуйц — Паттерн мэддэг хүн кодыг амархан ойлгоно
- Уян хатан дизайн — Өөрчлөлтөд нээлттэй, засвар хялбар
Паттерны 3 бүрэлдэхүүн хэсэг
Паттерн бүр гурван зүйлийг тодорхойлдог:
| Бүрэлдэхүүн | Тайлбар | Зүйрлэл |
|---|---|---|
| Асуудал (Problem) | Ямар нөхцөлд хэрэглэх вэ? | "Хоол амтгүй байна, юу хийх вэ?" |
| Контекст (Context) | Ямар нөхцөл байдалд хэрэглэх вэ? | "Монгол зочин байна, Монгол хоол хийх хэрэгтэй" |
| Шийдэл (Solution) | Хэрхэн шийдвэрлэх вэ? | "Бууз хийх жор: гурил, мах, сонгино..." |
1.2 Паттерны 3 том ангилал (Three Categories of Patterns)
GoF 23 паттерныг 3 том бүлэгт хуваадаг:
А) Бүтээх паттернууд (Creational Patterns) — 5 ш
Объект ЯАЖЕ ҮҮСГЭХ-тэй холбоотой. Объект үүсгэх процессыг хийсвэрлэж, системийг объект яаж үүссэнээс хамааралгүй болгодог.
Зүйрлэл: Автомашины үйлдвэр — захиалагч "Би седан авах" гэнэ. Үйлдвэр доторх нарийн үйл явцыг мэдэх шаардлагагүй — зүгээр л машин гарч ирнэ.
| # | Паттерн | Товч тайлбар |
|---|---|---|
| 1 | Singleton | Зөвхөн НЭГ объект үүсгэж, бүх газраас хандах |
| 2 | Factory Method | Объект үүсгэхийг дэд класст шилжүүлэх |
| 3 | Abstract Factory | Хамааралтай объектуудын гэр бүлийг нэг дор үүсгэх |
| 4 | Builder | Нарийн төвөгтэй объектыг алхам алхмаар бүтээх |
| 5 | Prototype | Одоо байгаа объектыг хуулбарлаж шинэ объект үүсгэх |
Б) Бүтцийн паттернууд (Structural Patterns) — 7 ш
Класс, объектуудыг ЯАЖЕ НЭГТГЭХ-тэй холбоотой. Объектуудыг том бүтцэд хэрхэн зохион байгуулахыг тодорхойлдог.
Зүйрлэл: LEGO — жижиг хэсгүүдийг хоорондоо холбож том бүтэц бүтээх. Хэсэг бүр өөрөө ч ажилладаг, бусадтай холбогдсон ч ажилладаг.
| # | Паттерн | Товч тайлбар |
|---|---|---|
| 1 | Adapter | Хоёр нийцдэггүй интерфейсийг холбох |
| 2 | Bridge | Хийсвэрлэлийг хэрэгжүүлэлтээс салгах |
| 3 | Composite | Объектуудыг модлог (tree) бүтцэд зохион байгуулах |
| 4 | Decorator | Объектод шинэ функц динамикаар нэмэх |
| 5 | Facade | Нарийн системд хялбар интерфейс хангах |
| 6 | Flyweight | Олон тооны ижил объектын санах ойг хэмнэх |
| 7 | Proxy | Өөр объектыг орлох, хандалтыг хянах |
В) Зан төлөвийн паттернууд (Behavioral Patterns) — 11 ш
Объектууд ЯАЖЕ ХАРИЛЦАХ-тай холбоотой. Алгоритм, хариуцлагыг хуваарилах аргуудыг тодорхойлдог.
Зүйрлэл: Хөл бөмбөгийн баг — тоглогч бүр өөрийн үүрэгтэй (хамгаалагч, дунд, довтлогч) бөгөөд тэд хоорондоо дохио, дамжуулалтаар харилцдаг. Паттерн нь энэ "харилцааны дүрмийг" тодорхойлдог.
| # | Паттерн | Товч тайлбар |
|---|---|---|
| 1 | Observer | Объектын төлөв өөрчлөгдөхөд бусдад мэдэгдэх |
| 2 | Strategy | Алгоритмыг сольж болдог болгох |
| 3 | Command | Хүсэлтийг объект болгож капсулжуулах |
| 4 | State | Объект төлөвөөс хамааран зан төлөвөө өөрчлөх |
| 5 | Template Method | Алгоритмын араг ясыг тодорхойлж, дэд класст нарийн хэсгийг шилжүүлэх |
| 6 | Iterator | Цуглуулгын элементүүдийг дараалуулан хандах |
| 7 | Mediator | Объектуудын харилцааг нэг цэгт төвлөрүүлэх |
| 8 | Memento | Объектын өмнөх төлөвийг хадгалж, сэргээх |
| 9 | Chain of Responsibility | Хүсэлтийг гинжин хэлхээгээр дамжуулах |
| 10 | Visitor | Бүтцээ өөрчлөхгүйгээр шинэ үйлдэл нэмэх |
| 11 | Interpreter | Хэлний дүрэм тодорхойлж, тайлбарлах |
1.3 Бүтээх паттернууд дэлгэрэнгүй (Creational Patterns in Detail)
1.3.1 Singleton — Ганцхан объект
Асуудал: Зарим тохиолдолд класснаас зөвхөн нэг объект үүсэх ёстой. Жишээ нь: мэдээллийн сангийн холболт, тохиргооны менежер, лог бичигч.
Зүйрлэл: Монгол улсад Ерөнхийлөгч ганцхан байдаг. Хэн ч шинээр Ерөнхийлөгч "үүсгэж" чадахгүй — одоо байгаа Ерөнхийлөгчийг л авч ашиглана.
Шийдэл:
- Constructor-ийг
privateболгох → гаднаасnewхийж чадахгүй - Статик
getInstance()метод хангах → Нэг л объект буцаана
public class DatabaseConnection {
// 1. Ганцхан instance-ийг static талбарт хадгалах
private static DatabaseConnection instance;
// 2. Constructor-ийг private болгох — гаднаас үүсгэж чадахгүй
private DatabaseConnection() {
System.out.println("Мэдээллийн сантай холбогдлоо!");
}
// 3. Ганцхан instance-д хандах цорын ганц арга
public static DatabaseConnection getInstance() {
if (instance == null) { // Хэрэв instance үүсээгүй бол
instance = new DatabaseConnection(); // Үүсгэнэ
}
return instance; // Байгаа instance-ийг буцаана
}
public void query(String sql) {
System.out.println("SQL ажиллууллаа: " + sql);
}
}
// Хэрэглээ:
// DatabaseConnection db1 = DatabaseConnection.getInstance();
// DatabaseConnection db2 = DatabaseConnection.getInstance();
// db1 == db2 → true (яг адилхан объект!)
Хэзээ ашиглах: Мэдээллийн сангийн холболт, Logger, Configuration, Thread pool
1.3.2 Factory Method — Үйлдвэрийн арга
Асуудал: Ямар класснаас объект үүсгэхийг код ажиллаж байх үед шийдэх шаардлагатай. Шинэ төрөл нэмэхэд одоо байгаа кодыг өөрчлөхгүй байх.
Зүйрлэл: Пиццаны дэлгүүр — Захиалагч "Пепперони пицца" гэнэ. Дэлгүүр дотор ЯАЖЕ бэлтгэхийг (овен, температур, хугацаа) мэдэх шаардлагагүй. Дэлгүүр (Factory) бэлэн пицца (Object) гаргаж өгнө.
// Бүтээгдэхүүний интерфейс
interface Notification {
void send(String message);
}
// Бодит бүтээгдэхүүнүүд
class EmailNotification implements Notification {
@Override
public void send(String message) {
System.out.println("📧 Email илгээлээ: " + message);
}
}
class SMSNotification implements Notification {
@Override
public void send(String message) {
System.out.println("📱 SMS илгээлээ: " + message);
}
}
class PushNotification implements Notification {
@Override
public void send(String message) {
System.out.println("🔔 Push мэдэгдэл: " + message);
}
}
// Factory — Объект үүсгэх үйлдвэр
class NotificationFactory {
public static Notification create(String type) {
switch (type.toLowerCase()) {
case "email": return new EmailNotification();
case "sms": return new SMSNotification();
case "push": return new PushNotification();
default: throw new IllegalArgumentException("Тодорхойгүй төрөл: " + type);
}
}
}
// Хэрэглээ:
// Notification notif = NotificationFactory.create("email");
// notif.send("Сайн байна уу!");
// → 📧 Email илгээлээ: Сайн байна уу!
Давуу тал: Шинэ төрөл нэмэхэд зөвхөн Factory-д нэг case нэмнэ → Бусад код өөрчлөгдөхгүй
1.3.3 Builder — Алхам алхмаар бүтээгч
Асуудал: Олон параметртэй нарийн төвөгтэй объект үүсгэх. Constructor-т 10+ параметр дамжуулах нь ойлгомжгүй.
Зүйрлэл: Бургер захиалах — "Том талх, давхар мах, бяслаг тийм, лоолийн соус, сонгиногүй" гэж алхам алхмаар хэлдэг. Бүгдийг нэг дор хэлэх шаардлагагүй.
public class Student {
private String name; // Заавал
private int age; // Заавал
private String email; // Нэмэлт
private String phone; // Нэмэлт
private String address; // Нэмэлт
// Private constructor — зөвхөн Builder-ээр үүсгэнэ
private Student(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.email = builder.email;
this.phone = builder.phone;
this.address = builder.address;
}
// Дотоод Builder класс
public static class Builder {
private String name; // Заавал
private int age; // Заавал
private String email; // Нэмэлт
private String phone; // Нэмэлт
private String address; // Нэмэлт
public Builder(String name, int age) { // Заавал талбарууд
this.name = name;
this.age = age;
}
public Builder email(String email) { // Нэмэлт талбарууд
this.email = email;
return this; // this буцааж chain хийх
}
public Builder phone(String phone) {
this.phone = phone;
return this;
}
public Builder address(String address) {
this.address = address;
return this;
}
public Student build() { // Эцсийн объект үүсгэх
return new Student(this);
}
}
@Override
public String toString() {
return "Оюутан: " + name + ", " + age + " нас"
+ (email != null ? ", " + email : "")
+ (phone != null ? ", " + phone : "");
}
}
// Хэрэглээ — уншихад маш ойлгомжтой:
// Student student = new Student.Builder("Бат", 20)
// .email("bat@email.com")
// .phone("99112233")
// .build();
1.3.4 Prototype — Хуулбарлагч
Асуудал: Объект үүсгэх нь нөөц их шаарддаг (мэдээллийн сангаас уншдаг, тооцоолол хийдэг). Одоо байгаа объектыг хуулбарлах нь хурдан.
Зүйрлэл: Ажлын байрны хүсэлтийн маягт — Эхний хүсэлтийг анхнаас бөглөнө. Дараагийнхийг ХУУЛБАРЛАЖ, өөрчлөх зүйлээ л засна.
public class Document implements Cloneable {
private String title;
private String content;
public Document(String title, String content) {
this.title = title;
this.content = content;
}
// Prototype — clone() метод
@Override
public Document clone() {
try {
return (Document) super.clone(); // Хуулбар үүсгэх
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
public void setTitle(String title) { this.title = title; }
public String toString() { return title + ": " + content; }
}
// Хэрэглээ:
// Document original = new Document("Гэрээ", "Энэ бол гэрээний агуулга...");
// Document copy = original.clone(); // Хуулбарлах
// copy.setTitle("Гэрээ - Хувилбар 2"); // Зөвхөн нэрийг өөрчлөх
1.4 Бүтцийн паттернууд дэлгэрэнгүй (Structural Patterns in Detail)
1.4.1 Adapter — Тохируулагч
Асуудал: Хоёр класс хоорондоо нийцдэггүй интерфейстэй ч хамт ажиллах шаардлагатай.
Зүйрлэл: Гадаадад аялахад залгуурын хэлбэр өөр байдаг. Adapter (залгуурын хувиргагч) ашиглаж Монгол залгуурыг Европын розеткад тохируулдаг шиг.
// Хуучин систем — зөвхөн XML мэддэг
class OldAnalytics {
public void analyzeXML(String xmlData) {
System.out.println("XML шинжилгээ: " + xmlData);
}
}
// Шинэ систем — JSON ашигладаг
interface ModernAnalytics {
void analyzeJSON(String jsonData);
}
// Adapter — Хуучин системийг шинэ интерфейсээр ашиглуулна
class AnalyticsAdapter implements ModernAnalytics {
private OldAnalytics oldAnalytics;
public AnalyticsAdapter(OldAnalytics oldAnalytics) {
this.oldAnalytics = oldAnalytics;
}
@Override
public void analyzeJSON(String jsonData) {
// JSON-ийг XML руу хувиргаж, хуучин системд дамжуулна
String xmlData = convertJsonToXml(jsonData);
oldAnalytics.analyzeXML(xmlData);
}
private String convertJsonToXml(String json) {
return "<data>" + json + "</data>"; // Хялбаршуулсан хувиргалт
}
}
1.4.2 Facade — Нүүр хаалга
Асуудал: Нарийн төвөгтэй системтэй харилцахад олон класс, метод дуудах шаардлагатай.
Зүйрлэл: Зочид буудлын ресепшн — Та ресепшнд л хэлнэ, тэд цэвэрлэгээ, хоол, такси бүгдийг зохион байгуулна. Та хоол хийгчтэй, жолоочтой шууд ярилцах шаардлагагүй.
// Нарийн төвөгтэй дэд системүүд
class VideoFile { /* видео файл уншигч */ }
class AudioExtractor { public void extract() { System.out.println("Аудио задлав"); } }
class VideoCompressor { public void compress() { System.out.println("Видео шахав"); } }
class CodecFactory { public void getCodec() { System.out.println("Кодек сонгов"); } }
// Facade — Нэг энгийн интерфейс
class VideoConverter {
public void convert(String filename, String format) {
System.out.println("=== " + filename + " → " + format + " руу хөрвүүлж байна ===");
new CodecFactory().getCodec();
new AudioExtractor().extract();
new VideoCompressor().compress();
System.out.println("=== Хөрвүүлэлт амжилттай! ===");
}
}
// Хэрэглээ — маш энгийн:
// VideoConverter converter = new VideoConverter();
// converter.convert("movie.avi", "mp4");
1.4.3 Decorator — Чимэглэгч
Асуудал: Объектод ажиллах үед шинэ функц динамикаар нэмэх. Удамшилаар шийдвэл класс тэсрэлт (class explosion) үүснэ.
Зүйрлэл: Кофе — Энгийн кофе + сүү = сүүтэй кофе. Сүүтэй кофе + чихэр = чихэртэй сүүтэй кофе. Хэрэглэгч хүссэн нэмэлтүүдээ давхарлаж "чимэглэнэ".
// Суурь интерфейс
interface Coffee {
double getCost();
String getDescription();
}
// Суурь бүтээгдэхүүн
class SimpleCoffee implements Coffee {
@Override
public double getCost() { return 2000; }
@Override
public String getDescription() { return "Энгийн кофе"; }
}
// Decorator суурь класс
abstract class CoffeeDecorator implements Coffee {
protected Coffee coffee;
public CoffeeDecorator(Coffee coffee) { this.coffee = coffee; }
}
// Бодит decorator-ууд
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) { super(coffee); }
@Override
public double getCost() { return coffee.getCost() + 500; }
@Override
public String getDescription() { return coffee.getDescription() + " + Сүү"; }
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) { super(coffee); }
@Override
public double getCost() { return coffee.getCost() + 200; }
@Override
public String getDescription() { return coffee.getDescription() + " + Чихэр"; }
}
// Хэрэглээ:
// Coffee coffee = new SimpleCoffee(); // Энгийн кофе: 2000₮
// coffee = new MilkDecorator(coffee); // + Сүү: 2500₮
// coffee = new SugarDecorator(coffee); // + Чихэр: 2700₮
// System.out.println(coffee.getDescription() + " = " + coffee.getCost() + "₮");
// → "Энгийн кофе + Сүү + Чихэр = 2700₮"
1.4.4 Proxy — Орлогч
Асуудал: Объектод хандахыг хянах, хойшлуулах, эсвэл нэмэлт логик нэмэх шаардлагатай.
Зүйрлэл: Нарийн бичгийн дарга — Та захиралтай уулзахын тулд нарийн бичгийн даргаар дамжина. Тэр таны цагийг товлох, хандалтыг шалгах, захиралд мэдэгдэх зэргийг хийнэ.
interface Image {
void display();
}
// Бодит объект — Их нөөц шаарддаг
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk(); // Их цаг зарцуулдаг
}
private void loadFromDisk() {
System.out.println("Дискнээс ачааллаж байна: " + filename);
}
@Override
public void display() {
System.out.println("Зураг харуулж байна: " + filename);
}
}
// Proxy — Бодит объектын орлогч
class ProxyImage implements Image {
private String filename;
private RealImage realImage; // Lazy loading
public ProxyImage(String filename) {
this.filename = filename; // Зүгээр нэрийг хадгална
}
@Override
public void display() {
if (realImage == null) { // Анх удаа дуудахад л ачаална
realImage = new RealImage(filename);
}
realImage.display();
}
}
1.5 Зан төлөвийн паттернууд дэлгэрэнгүй (Behavioral Patterns in Detail)
1.5.1 Observer — Ажиглагч
Асуудал: Нэг объектын төлөв өөрчлөгдөхөд олон объектод автоматаар мэдэгдэх шаардлагатай.
Зүйрлэл: YouTube суваг дагах (subscribe) — Шинэ видео нийтлэгдэхэд бүх дагагчдад мэдэгдэл очдог. Дагагч нэмэх, хасах нь сувагт нөлөөлөхгүй.
import java.util.ArrayList;
import java.util.List;
// Observer интерфейс — Мэдэгдэл хүлээн авагч
interface Subscriber {
void update(String channelName, String videoTitle);
}
// Subject — Мэдэгдэл илгээгч (YouTube суваг)
class YouTubeChannel {
private String name;
private List<Subscriber> subscribers = new ArrayList<>();
public YouTubeChannel(String name) { this.name = name; }
public void subscribe(Subscriber sub) {
subscribers.add(sub);
System.out.println("✅ Шинэ дагагч нэмэгдлээ!");
}
public void unsubscribe(Subscriber sub) {
subscribers.remove(sub);
}
// Шинэ видео нийтлэхэд БҮХ дагагчдад мэдэгдэнэ
public void publishVideo(String title) {
System.out.println("🎬 Шинэ видео: " + title);
for (Subscriber sub : subscribers) {
sub.update(name, title); // Бүх дагагчид мэдэгдэх
}
}
}
// Бодит Observer
class User implements Subscriber {
private String name;
public User(String name) { this.name = name; }
@Override
public void update(String channelName, String videoTitle) {
System.out.println("🔔 " + name + " → " + channelName + ": \"" + videoTitle + "\"");
}
}
// Хэрэглээ:
// YouTubeChannel channel = new YouTubeChannel("TechMN");
// channel.subscribe(new User("Бат"));
// channel.subscribe(new User("Болд"));
// channel.publishVideo("Java Design Patterns");
// → 🔔 Бат → TechMN: "Java Design Patterns"
// → 🔔 Болд → TechMN: "Java Design Patterns"
1.5.2 Strategy — Стратеги
Асуудал: Нэг ажлыг олон өөр аргаар хийж болох бөгөөд ажиллах үед аргаа сольж болох ёстой.
Зүйрлэл: Ажил руугаа явах — Автобусаар, таксиар, алхаж, дугуйгаар... Зорилго нэг (ажил руу хүрэх), арга олон. Цаг агаар, мөнгөнөөсөө хамааран аргаа сонгоно.
// Strategy интерфейс
interface PaymentStrategy {
void pay(int amount);
}
// Бодит стратегиуд
class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
public CreditCardPayment(String cardNumber) { this.cardNumber = cardNumber; }
@Override
public void pay(int amount) {
System.out.println("💳 Картаар төлөв: " + amount + "₮ (Карт: " + cardNumber + ")");
}
}
class QPayPayment implements PaymentStrategy {
private String phoneNumber;
public QPayPayment(String phoneNumber) { this.phoneNumber = phoneNumber; }
@Override
public void pay(int amount) {
System.out.println("📱 QPay-ээр төлөв: " + amount + "₮ (Утас: " + phoneNumber + ")");
}
}
class CashPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println("💵 Бэлнээр төлөв: " + amount + "₮");
}
}
// Context — Стратегийг ашиглагч
class ShoppingCart {
private PaymentStrategy paymentStrategy;
public void setPaymentStrategy(PaymentStrategy strategy) {
this.paymentStrategy = strategy; // Стратегийг солих
}
public void checkout(int amount) {
paymentStrategy.pay(amount); // Сонгосон стратегиар төлөх
}
}
// Хэрэглээ:
// ShoppingCart cart = new ShoppingCart();
// cart.setPaymentStrategy(new QPayPayment("99112233"));
// cart.checkout(50000);
// → 📱 QPay-ээр төлөв: 50000₮ (Утас: 99112233)
1.5.3 Template Method — Загвар арга
Асуудал: Алгоритмын ерөнхий бүтэц ижил, гэхдээ зарим алхмууд өөр өөр.
Зүйрлэл: Хоол хийх ерөнхий дараалал — (1) орцыг бэлтгэ, (2) хоолоо хий, (3) таваглаж өг. Бууз ч, хуушуур ч, банш ч энэ дарааллаар хийгдэнэ — зөвхөн нарийн алхмууд нь өөр.
// Template Method — Ерөнхий араг яс
abstract class MealPreparation {
// Template method — дарааллыг тодорхойлно (final = дэд класс өөрчилж чадахгүй)
public final void prepareMeal() {
prepareIngredients();
cook();
serve();
}
abstract void prepareIngredients(); // Дэд класс тодорхойлно
abstract void cook(); // Дэд класс тодорхойлно
void serve() { // Ерөнхий хэрэгжүүлэлт
System.out.println("🍽️ Таваглаж өгөв!");
}
}
class BuuzPreparation extends MealPreparation {
@Override
void prepareIngredients() {
System.out.println("🥟 Гурил зуурч, мах бэлтгэв");
}
@Override
void cook() {
System.out.println("♨️ Жигнэж байна... 20 минут");
}
}
class PizzaPreparation extends MealPreparation {
@Override
void prepareIngredients() {
System.out.println("🍕 Гурил дэлгэж, соус, бяслаг тавив");
}
@Override
void cook() {
System.out.println("🔥 Зууханд шаржигнуулж байна... 15 минут");
}
}
1.5.4 Command — Команд
Асуудал: Хүсэлтийг объект болгож хадгалах, дараалалд оруулах, буцаах (undo) шаардлагатай.
Зүйрлэл: Ресторанд захиалга өгөх — Зөөгч таны захиалгыг цаасан дээр бичиж (Command объект), гал тогоонд дамжуулна. Захиалгыг цуцлах (undo), дараалалд оруулах боломжтой.
// Command интерфейс
interface Command {
void execute();
void undo();
}
// Receiver — Бодит ажлыг гүйцэтгэгч
class Light {
public void turnOn() { System.out.println("💡 Гэрэл асав!"); }
public void turnOff() { System.out.println("🌑 Гэрэл унтрав!"); }
}
// Бодит Command-ууд
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) { this.light = light; }
@Override
public void execute() { light.turnOn(); }
@Override
public void undo() { light.turnOff(); }
}
// Invoker — Command-ыг ажиллуулагч
class RemoteControl {
private Command lastCommand;
public void pressButton(Command command) {
command.execute();
lastCommand = command;
}
public void pressUndo() {
if (lastCommand != null) {
lastCommand.undo();
}
}
}
1.6 Паттерн хэрэглэх зарчмууд (When and How to Use Patterns)
Хэрэглэх ёстой үед:
- Давтагддаг асуудал илэрсэн үед
- Уян хатан дизайн шаардлагатай үед
- Багийн харилцааг сайжруулах үед
Хэрэглэх ёсгүй үед:
- Хэт энгийн асуудалд паттерн хэрэглэх нь over-engineering
- Паттерн нь кодын нарийн төвөгтэй байдлыг нэмдэг — зөвхөн шаардлагатай үед ашиглах
- Паттерн хэрэглэх гэж хэрэглэхгүй — Асуудлаа тодорхой ойлгоод, паттерн тохирох эсэхийг шалгах
"When Not to Use Design Patterns" — GoF номноос: "Хамгийн энгийн шийдэл нь хамгийн сайн шийдэл. Паттерн нь зөвхөн нарийн төвөгтэй байдал зөвтгөгдөх үед ашиглагдах ёстой."
SOLID зарчмууд ба Design Patterns
Дизайн паттернууд нь SOLID зарчмуудыг хэрэгжүүлэхэд тусалдаг:
| SOLID зарчим | Тайлбар | Холбоотой паттерн |
|---|---|---|
| S — Single Responsibility | Нэг класс нэг л үүрэгтэй | Command, Strategy |
| O — Open/Closed | Өргөтгөхөд нээлттэй, өөрчлөхөд хаалттай | Decorator, Observer |
| L — Liskov Substitution | Дэд класс эцэг классыг орлож чадах | Factory, Template Method |
| I — Interface Segregation | Интерфейсийг жижиглэх | Adapter, Facade |
| D — Dependency Inversion | Хийсвэрлэлээс хамаарах, бодит хэрэгжүүлэлтээс биш | Factory, Strategy |
ХЭСЭГ 2: ТҮЛХҮҮР ҮГ БА МЭРГЭЖЛИЙН НЭР ТОМЬЁО (Keywords & Glossary)
| # | Англи нэр томьёо | Монгол утга | Дэлгэрэнгүй тайлбар |
|---|---|---|---|
| 1 | Design Pattern | Дизайн паттерн / Загвар хэв | Програм хангамжийн дизайнд байнга давтагддаг асуудлыг шийдвэрлэх батлагдсан загвар. Хоолны жортой адил — нэг удаа сурч, олон удаа ашиглана. |
| 2 | Gang of Four (GoF) | Дөрвөн хүний бүлэг | 1995 онд "Design Patterns" номыг бичсэн 4 зохиогч: Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. |
| 3 | Creational Pattern | Бүтээх паттерн | Объект ЯАЖЕ үүсгэхтэй холбоотой паттерн. Объект үүсгэх процессыг хийсвэрлэж, системийг уян хатан болгодог. |
| 4 | Structural Pattern | Бүтцийн паттерн | Класс, объектуудыг ЯАЖЕ нэгтгэхтэй холбоотой. Том бүтэц зохион байгуулах арга замыг тодорхойлдог. |
| 5 | Behavioral Pattern | Зан төлөвийн паттерн | Объектууд ЯАЖЕ харилцахтай холбоотой. Алгоритм, хариуцлагыг хуваарилах аргуудыг тодорхойлдог. |
| 6 | Singleton | Ганцаардмал | Зөвхөн НЭГ объект үүсгэж, глобал хандалт хангах паттерн. Ерөнхийлөгч ганцхан байдаг шиг. |
| 7 | Factory Method | Үйлдвэрийн арга | Объект үүсгэх үүргийг дэд класст шилжүүлдэг. Пиццаны дэлгүүр шиг — захиалга өгөхөд бэлэн бүтээгдэхүүн гарна. |
| 8 | Abstract Factory | Хийсвэр үйлдвэр | Хамааралтай объектуудын ГЭР БҮЛИЙГ нэг дор үүсгэдэг. Тавилга дэлгүүрийн каталог шиг — "Модерн" сонговол бүх тавилга модерн. |
| 9 | Builder | Бүтээгч | Нарийн төвөгтэй объектыг алхам алхмаар бүтээх. Бургер захиалах шиг — орц бүрийг тусдаа сонгоно. |
| 10 | Prototype | Эх загвар / Хуулбарлагч | Одоо байгаа объектыг хуулбарлаж шинэ объект үүсгэх. Маягтыг хуулбарлаад зөвхөн өөрчлөх зүйлээ засах шиг. |
| 11 | Adapter | Тохируулагч / Залгуур хувиргагч | Нийцдэггүй хоёр интерфейсийг холбодог. Гадаадын залгуурын хувиргагч шиг. |
| 12 | Facade | Нүүр хаалга | Нарийн системд хялбар, ганцхан интерфейс хангадаг. Зочид буудлын ресепшн шиг — бүх зүйлийг нэг цэгээс шийднэ. |
| 13 | Decorator | Чимэглэгч | Объектод шинэ функц динамикаар давхарлаж нэмдэг. Кофенд сүү, чихэр нэмдэг шиг. |
| 14 | Proxy | Орлогч / Төлөөлөгч | Өөр объектын орлуулагч бөгөөд хандалтыг хянаж, нэмэлт логик нэмдэг. Нарийн бичгийн дарга шиг. |
| 15 | Observer | Ажиглагч | Объектын төлөв өөрчлөгдөхөд бүх дагагчдад мэдэгдэдэг. YouTube subscribe шиг. |
| 16 | Strategy | Стратеги | Олон алгоритмаас ажиллах үед сонгож болдог. Ажил руугаа явах олон арга шиг — автобус, такси, алхах. |
| 17 | Template Method | Загвар арга | Алгоритмын бүтцийг тогтоож, нарийн алхмуудыг дэд класст шилжүүлдэг. Бууз, хуушууры ерөнхий "хоол хийх" дараалал ижил, нарийн нь өөр. |
| 18 | Command | Команд | Хүсэлтийг объект болгож хадгалах, дараалалд оруулах, буцаах (undo). Ресторанд захиалгын цаас шиг. |
| 19 | State | Төлөв | Объект дотоод төлөвөөс хамаарч зан төлөвөө өөрчилдөг. Гар утас: дуугүй горимд дуугардаггүй, чимээтэй горимд дуугардаг. |
| 20 | Iterator | Давталтчин | Цуглуулгын элементүүдийг дотоод бүтцийг далдалж дараалуулан хандах. TV-ийн суваг солигч шиг — дарах бүрт дараагийн суваг. |
| 21 | Mediator | Зуучлагч | Объектуудын шууд харилцааг зогсоож, бүхнийг нэг зуучлагчаар дамжуулдаг. Нисэх буудлын удирдах цамхаг шиг. |
| 22 | Memento | Дурсгал / Хадгалагч | Объектын өмнөх төлөвийг хадгалж, хэрэгтэй үед сэргээдэг. Тоглоомын "save point" шиг. |
| 23 | Chain of Responsibility | Хариуцлагын гинж | Хүсэлтийг гинжин хэлхээгээр дамжуулж, тохирох зохицуулагч олтол дамжуулдаг. Байгууллагад өргөдөл дамжуулах шиг. |
| 24 | Visitor | Зочин | Объектын бүтцийг өөрчлөхгүйгээр шинэ үйлдэл нэмэх. Гэрийн эзэн зочинд гэрээ нээж өгдөг шиг — зочин шинэ үйлдэл хийнэ. |
| 25 | Bridge | Гүүр | Хийсвэрлэлийг хэрэгжүүлэлтээс салгаж, тус тусдаа хөгжүүлэх. Удирдлагын пульт (хийсвэрлэл) ба ТВ (хэрэгжүүлэлт) тусдаа. |
| 26 | Composite | Нийлмэл | Объектуудыг мод (tree) бүтцэд зохион байгуулж, нэг объект шиг хандах. Файлын систем: фолдер дотор файл ба фолдер байна. |
| 27 | Flyweight | Хөнгөн жин | Олон ижил объектын нийтлэг өгөгдлийг хуваалцуулж санах ойг хэмнэдэг. Тоглоомд олон мод ижил бүтэцтэй — зүгээр байрлал нь өөр. |
| 28 | Interpreter | Тайлбарлагч | Хэлний дүрэм тодорхойлж, өгүүлбэрийг тайлбарлах. SQL query-г задлан шинжлэх шиг. |
| 29 | SOLID | SOLID зарчмууд | Объект хандлагат дизайны 5 суурь зарчим: Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion. |
| 30 | Open/Closed Principle | Нээлттэй/Хаалттай зарчим | Класс ӨРГӨТГӨХӨД нээлттэй, ӨӨРЧЛӨХӨД хаалттай байх ёстой. Decorator, Strategy паттернууд үүнийг хэрэгжүүлдэг. |
| 31 | Dependency Inversion | Хамааралын урвуу | Дээд түвшний модуль доод түвшний модулиас хамаарах ёсгүй — хоёулаа хийсвэрлэлээс хамаарах ёстой. |
| 32 | Loose Coupling | Сул холбоос | Модулиуд хоорондоо аль болох бага хамааралтай байх. Паттернуудын ихэнх нь үүнийг зорьдог. |
| 33 | Interface | Интерфейс | Класс ямар үйлдлүүд хийж чадахыг тодорхойлсон гэрээ. Хэрэгжүүлэлтийг заадаггүй, зөвхөн "юу хийх"-ийг заадаг. |
| 34 | Abstract Class | Хийсвэр класс | Дутуу хэрэгжүүлэлттэй (abstract method-тэй) класс. Шууд объект үүсгэж болохгүй, зөвхөн удамшуулна. |
| 35 | Inheritance | Удамшил | Нэг классаас шинж чанар, үйлдлүүдийг өвлөн авах. Хүүхэд эцэг эхийнхээ зарим шинж чанарыг өвлөдөг шиг. |
| 36 | Composition | Бүтэц / Нийлбэр | Объектыг бусад объектуудаас бүрдүүлэх. "HAS-A" харилцаа. Машин = мотор + дугуй + бие. |
| 37 | Encapsulation | Капсулжуулалт | Өгөгдөл ба методыг нэгтгэж, гаднаас шууд хандахыг хязгаарлах. |
| 38 | Polymorphism | Олон хэлбэрт байдал | Нэг интерфейсээр өөр өөр хэрэгжүүлэлтийг дуудах чадвар. Strategy, Observer паттернуудын суурь. |
| 39 | Over-engineering | Хэт инженерчлэл | Шаардлагагүй нарийн төвөгтэй шийдэл хэрэглэх. Паттерн хэрэггүй газар паттерн хэрэглэх жишээ. |
| 40 | Design for Change | Өөрчлөлтөд зориулсан дизайн | GoF-ийн гол зарчим — систем дизайнлахдаа зайлшгүй ирэх өөрчлөлтийг урьдчилан тооцох. |
ХЭСЭГ 3: ЛАБОРАТОРИ БА ПРАКТИК ЗААВАР (Labs & Step-by-Step Guide)
3.1 Лабораторийн зорилго
Энэ лабораторид та 4 үндсэн дизайн паттерныг Java дээр бие даан хэрэгжүүлнэ:
- Singleton
- Factory Method
- Observer
- Strategy
Шаардлагатай зүйлс: Лекц 01-д суулгасан Java JDK 17+ ба Eclipse IDE
3.2 Лаб 1: Singleton паттерн — Тохиргооны менежер
Даалгавар: Програмын тохиргоог удирдах ConfigManager класс бичих. Зөвхөн нэг объект байх ёстой.
Алхам 1: Eclipse-д шинэ төсөл үүсгэнэ (File → New → Java Project): DesignPatternsLab
Алхам 2: ConfigManager.java файл үүсгэнэ:
import java.util.HashMap;
import java.util.Map;
public class ConfigManager {
// === Singleton хэрэгжүүлэлт ===
// 1. Ганцхан instance хадгалах static талбар
private static ConfigManager instance;
// 2. Тохиргооны утгуудыг хадгалах map
private Map<String, String> settings;
// 3. Private constructor — гаднаас new хийж чадахгүй
private ConfigManager() {
settings = new HashMap<>();
// Анхдагч тохиргоо
settings.put("language", "mn"); // Хэл: Монгол
settings.put("theme", "dark"); // Загвар: Харанхуй
settings.put("fontSize", "14"); // Фонт хэмжээ: 14
System.out.println("✅ ConfigManager үүслээ!");
}
// 4. Ганцхан instance-д хандах арга
public static ConfigManager getInstance() {
if (instance == null) { // Анх удаа дуудахад л үүсгэнэ
instance = new ConfigManager();
}
return instance;
}
// 5. Тохиргоо авах
public String get(String key) {
return settings.getOrDefault(key, "тодорхойгүй");
}
// 6. Тохиргоо тохируулах
public void set(String key, String value) {
settings.put(key, value);
System.out.println("⚙️ Тохиргоо өөрчлөгдлөө: " + key + " = " + value);
}
// 7. Бүх тохиргоог харуулах
public void showAll() {
System.out.println("\n📋 Бүх тохиргоо:");
for (Map.Entry<String, String> entry : settings.entrySet()) {
System.out.println(" " + entry.getKey() + " = " + entry.getValue());
}
}
}
Алхам 3: SingletonTest.java файлд тестлэх:
public class SingletonTest {
public static void main(String[] args) {
// Анхны instance авах
ConfigManager config1 = ConfigManager.getInstance();
config1.showAll();
// Тохиргоо өөрчлөх
config1.set("theme", "light");
config1.set("fontSize", "16");
// Хоёр дахь instance авах — ижил объект байх ёстой!
ConfigManager config2 = ConfigManager.getInstance();
config2.showAll();
// Шалгах: хоёулаа ижил объект уу?
System.out.println("\nconfig1 == config2: " + (config1 == config2));
// → true (яг нэг объект!)
// ConfigManager cm = new ConfigManager(); // ← АЛДАА! private constructor
}
}
Хүлээгдэх үр дүн:
✅ ConfigManager үүслээ!
📋 Бүх тохиргоо:
language = mn
theme = dark
fontSize = 14
⚙️ Тохиргоо өөрчлөгдлөө: theme = light
⚙️ Тохиргоо өөрчлөгдлөө: fontSize = 16
📋 Бүх тохиргоо:
language = mn
theme = light
fontSize = 16
config1 == config2: true
3.3 Лаб 2: Factory Method паттерн — Дүрс үүсгэгч
Даалгавар: Өөр өөр дүрс (Shape) үүсгэдэг Factory бичих.
// ===== Shape интерфейс =====
interface Shape {
void draw(); // Дүрс зурах
double getArea(); // Талбай тооцоолох
}
// ===== Бодит дүрсүүд =====
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("⭕ Тойрог зурлаа (радиус: " + radius + ")");
}
@Override
public double getArea() {
return Math.PI * radius * radius; // S = πr²
}
}
class Rectangle implements Shape {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("⬜ Тэгш өнцөгт зурлаа (" + width + " x " + height + ")");
}
@Override
public double getArea() {
return width * height; // S = w × h
}
}
class Triangle implements Shape {
private double base, height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public void draw() {
System.out.println("🔺 Гурвалжин зурлаа (суурь: " + base + ", өндөр: " + height + ")");
}
@Override
public double getArea() {
return 0.5 * base * height; // S = ½ × b × h
}
}
// ===== Factory =====
class ShapeFactory {
public static Shape create(String type, double... params) {
switch (type.toLowerCase()) {
case "circle":
return new Circle(params[0]);
case "rectangle":
return new Rectangle(params[0], params[1]);
case "triangle":
return new Triangle(params[0], params[1]);
default:
throw new IllegalArgumentException("Тодорхойгүй дүрс: " + type);
}
}
}
// ===== Тест =====
class FactoryTest {
public static void main(String[] args) {
// Factory-аар дүрсүүд үүсгэх
Shape circle = ShapeFactory.create("circle", 5);
Shape rect = ShapeFactory.create("rectangle", 4, 6);
Shape tri = ShapeFactory.create("triangle", 3, 8);
// Бүгдийг зурж, талбайг тооцоолох
Shape[] shapes = {circle, rect, tri};
for (Shape s : shapes) {
s.draw();
System.out.println(" Талбай: " + String.format("%.2f", s.getArea()));
}
}
}
3.4 Лаб 3: Observer паттерн — Цаг агаарын мэдээ
Даалгавар: Цаг агаарын станц өгөгдөл өөрчлөгдөхөд бүх дэлгэцүүдэд мэдэгдэх систем бичих.
import java.util.ArrayList;
import java.util.List;
// ===== Observer интерфейс =====
interface WeatherDisplay {
void update(double temperature, double humidity);
}
// ===== Subject — Цаг агаарын станц =====
class WeatherStation {
private List<WeatherDisplay> displays = new ArrayList<>();
private double temperature;
private double humidity;
// Дэлгэц бүртгэх
public void addDisplay(WeatherDisplay display) {
displays.add(display);
}
// Дэлгэц хасах
public void removeDisplay(WeatherDisplay display) {
displays.remove(display);
}
// Өгөгдөл шинэчлэгдэхэд бүх дэлгэцэд мэдэгдэх
public void setMeasurements(double temperature, double humidity) {
this.temperature = temperature;
this.humidity = humidity;
System.out.println("\n🌡️ Шинэ хэмжилт: " + temperature + "°C, " + humidity + "% чийгшил");
notifyDisplays();
}
private void notifyDisplays() {
for (WeatherDisplay display : displays) {
display.update(temperature, humidity);
}
}
}
// ===== Бодит дэлгэцүүд =====
class PhoneDisplay implements WeatherDisplay {
private String ownerName;
public PhoneDisplay(String ownerName) { this.ownerName = ownerName; }
@Override
public void update(double temperature, double humidity) {
System.out.println("📱 " + ownerName + "-ийн утас: " + temperature + "°C, " + humidity + "%");
}
}
class TVDisplay implements WeatherDisplay {
private String channel;
public TVDisplay(String channel) { this.channel = channel; }
@Override
public void update(double temperature, double humidity) {
String feeling = temperature < 0 ? "❄️ Хүйтэн" : temperature < 20 ? "🌤️ Сэрүүн" : "☀️ Дулаан";
System.out.println("📺 " + channel + ": " + feeling + " " + temperature + "°C");
}
}
// ===== Тест =====
class ObserverTest {
public static void main(String[] args) {
// Станц үүсгэх
WeatherStation station = new WeatherStation();
// Дэлгэцүүд бүртгэх
PhoneDisplay bat = new PhoneDisplay("Бат");
PhoneDisplay bold = new PhoneDisplay("Болд");
TVDisplay mnb = new TVDisplay("MNB");
station.addDisplay(bat);
station.addDisplay(bold);
station.addDisplay(mnb);
// Хэмжилт шинэчлэх → Бүгдэд мэдэгдэнэ
station.setMeasurements(25.5, 60);
station.setMeasurements(-15.0, 80);
// Болдын дэлгэцийг хасах
station.removeDisplay(bold);
station.setMeasurements(10.0, 45);
}
}
3.5 Лаб 4: Strategy паттерн — Хөнгөлөлтийн систем
Даалгавар: Дэлгүүрийн хөнгөлөлтийн олон стратеги (хувиар, тогтмол дүнгээр, шинэ жилийн) хэрэгжүүлэх.
// ===== Strategy интерфейс =====
interface DiscountStrategy {
double applyDiscount(double originalPrice);
String getDescription();
}
// ===== Бодит стратегиуд =====
class PercentageDiscount implements DiscountStrategy {
private double percent;
public PercentageDiscount(double percent) { this.percent = percent; }
@Override
public double applyDiscount(double originalPrice) {
return originalPrice * (1 - percent / 100);
}
@Override
public String getDescription() {
return percent + "% хөнгөлөлт";
}
}
class FixedDiscount implements DiscountStrategy {
private double amount;
public FixedDiscount(double amount) { this.amount = amount; }
@Override
public double applyDiscount(double originalPrice) {
return Math.max(0, originalPrice - amount); // 0-ээс бага болохгүй
}
@Override
public String getDescription() {
return amount + "₮ хөнгөлөлт";
}
}
class NewYearDiscount implements DiscountStrategy {
@Override
public double applyDiscount(double originalPrice) {
if (originalPrice > 100000) {
return originalPrice * 0.7; // 100,000₮-аас дээш → 30% хөнгөлөлт
}
return originalPrice * 0.9; // Бусад → 10% хөнгөлөлт
}
@Override
public String getDescription() {
return "🎄 Шинэ жилийн хөнгөлөлт (100K+ → 30%, бусад → 10%)";
}
}
// ===== Context — Дэлгүүр =====
class Shop {
private DiscountStrategy discountStrategy;
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
System.out.println("🏷️ Стратеги: " + strategy.getDescription());
}
public void checkout(String item, double price) {
double finalPrice = discountStrategy.applyDiscount(price);
System.out.println(" " + item + ": " + price + "₮ → "
+ String.format("%.0f", finalPrice) + "₮"
+ " (хэмнэлт: " + String.format("%.0f", price - finalPrice) + "₮)");
}
}
// ===== Тест =====
class StrategyTest {
public static void main(String[] args) {
Shop shop = new Shop();
// Стратеги 1: 20% хөнгөлөлт
shop.setDiscountStrategy(new PercentageDiscount(20));
shop.checkout("Өвлийн курт", 150000);
// Стратеги 2: 5000₮ хөнгөлөлт
shop.setDiscountStrategy(new FixedDiscount(5000));
shop.checkout("Номхон", 25000);
// Стратеги 3: Шинэ жилийн хөнгөлөлт
shop.setDiscountStrategy(new NewYearDiscount());
shop.checkout("Зурагт", 500000);
shop.checkout("Чихэвч", 30000);
}
}
ХЭСЭГ 4: ШАЛГАЛТЫН АСУУЛТ (Knowledge Check — 100 тест)
Тест 1
Design Pattern гэж юу вэ?
- A) Програмчлалын хэлний стандарт
- B) Давтагддаг дизайны асуудлыг шийдвэрлэх батлагдсан загвар
- C) Кодыг автоматаар бичих хэрэгсэл
- D) Тестийн фреймворк
Зөв хариулт: B
Тайлбар: GoF-ийн тодорхойлолтоор design pattern нь "тодорхой контекст дэх ерөнхий дизайны асуудлыг шийдвэрлэх загвар". Хоолны жор шиг — батлагдсан, дахин ашиглагдах шийдэл.
Тест 2
"Gang of Four" (GoF) гэж хэн бэ?
- A) 4 програмчлалын хэлний зохиогчид
- B) "Design Patterns" номыг бичсэн 4 зохиогч
- C) Java хэлийг бүтээсэн 4 хүн
- D) Agile Manifesto-г зохиосон 4 хүн
Зөв хариулт: B
Тайлбар: GoF = Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. 1995 онд "Design Patterns: Elements of Reusable Object-Oriented Software" номыг бичсэн.
Тест 3
GoF номонд нийт хэдэн паттерн тодорхойлогдсон вэ?
- A) 10
- B) 15
- C) 23
- D) 30
Зөв хариулт: C
Тайлбар: GoF номонд нийт 23 паттерн: Creational (5), Structural (7), Behavioral (11) тодорхойлогдсон.
Тест 4
Дизайн паттерны 3 том ангилал аль нь вэ?
- A) Input, Process, Output
- B) Creational, Structural, Behavioral
- C) Simple, Medium, Complex
- D) Frontend, Backend, Database
Зөв хариулт: B
Тайлбар: GoF 23 паттерныг 3 бүлэгт хуваана: Creational (Бүтээх — объект яаж үүсгэх), Structural (Бүтцийн — объект яаж нэгтгэх), Behavioral (Зан төлөвийн — объект яаж харилцах).
Тест 5
Creational Pattern юутай холбоотой вэ?
- A) Объект хоорондын харилцаа
- B) Объект яаж үүсгэхтэй
- C) Класс хоорондын бүтэцтэй
- D) Алгоритмын оновчлолтой
Зөв хариулт: B
Тайлбар: Creational patterns нь объект ЯАЖЕ ҮҮСГЭХ-тэй холбоотой. Объект үүсгэх процессыг хийсвэрлэж, системийг уян хатан болгодог.
Тест 6
Structural Pattern юутай холбоотой вэ?
- A) Объект үүсгэхтэй
- B) Класс, объектуудыг том бүтцэд нэгтгэхтэй
- C) Алгоритм тодорхойлохтой
- D) Мэдээллийн сангийн бүтэцтэй
Зөв хариулт: B
Тайлбар: Structural patterns нь класс, объектуудыг ЯАЖЕ НЭГТГЭХ-тэй холбоотой. LEGO шиг — жижиг хэсгүүдийг нэгтгэж том бүтэц бүтээх.
Тест 7
Behavioral Pattern юутай холбоотой вэ?
- A) Объект үүсгэхтэй
- B) Бүтэц зохион байгуулахтай
- C) Объектуудын хоорондын харилцаа, алгоритмын хуваарилалттай
- D) Хурдны оновчлолтой
Зөв хариулт: C
Тайлбар: Behavioral patterns нь объектууд ЯАЖЕ ХАРИЛЦАХ-тай холбоотой. Алгоритм, хариуцлагыг хуваарилах, loose coupling хангах арга замыг тодорхойлдог.
Тест 8
Singleton паттерны зорилго юу вэ?
- A) Олон объект үүсгэх
- B) Зөвхөн нэг объект үүсгэж, глобал хандалт хангах
- C) Объект устгах
- D) Объектыг хуулбарлах
Зөв хариулт: B
Тайлбар: Singleton нь класснаас зөвхөн НЭГ объект үүсгэж, бүх газраас тэр объектод хандах боломж олгодог. Constructor-ийг private болгож, getInstance() метод хангадаг.
Тест 9
Singleton-д constructor яагаад private байдаг вэ?
- A) Компайлер шаарддаг
- B) Гаднаас new хийж шинэ объект үүсгэхээс сэргийлэх
- C) Код уншихад хялбар болгох
- D) Хурдыг нэмэгдүүлэх
Зөв хариулт: B
Тайлбар: Constructor private байвал гаднаас
new ClassName()хийж чадахгүй → ЗөвхөнgetInstance()методоор ганцхан объектод хандана.
Тест 10
Factory Method паттерны зорилго юу вэ?
- A) Объектыг устгах
- B) Объект үүсгэх үүргийг дэд класст шилжүүлэх
- C) Объектыг хуулбарлах
- D) Объектын төлөвийг хадгалах
Зөв хариулт: B
Тайлбар: Factory Method нь объект үүсгэх логикийг Factory класст төвлөрүүлж, клиент кодыг бодит классуудаас хамааралгүй болгодог.
Тест 11
Builder паттерныг хэзээ ашиглах вэ?
- A) Энгийн объект үүсгэхэд
- B) Олон параметртэй нарийн төвөгтэй объект үүсгэхэд
- C) Объект устгахад
- D) Тест бичихэд
Зөв хариулт: B
Тайлбар: Builder нь 10+ параметртэй нарийн төвөгтэй объектыг алхам алхмаар бүтээхэд хэрэглэгддэг. Уншихад ойлгомжтой, алдаа бага.
Тест 12
Prototype паттерн юу хийдэг вэ?
- A) Шинэ класс зарлах
- B) Одоо байгаа объектыг хуулбарлаж шинэ объект үүсгэх
- C) Объектын төлөвийг сэргээх
- D) Интерфейс тодорхойлох
Зөв хариулт: B
Тайлбар: Prototype нь
clone()методоор одоо байгаа объектыг хуулбарлаж шинэ объект үүсгэдэг. Объект үүсгэхэд нөөц их шаарддаг тохиолдолд ашигтай.
Тест 13
Adapter паттерныг амьдрал дээр юутай зүйрлэж болох вэ?
- A) Ресторанд цэс
- B) Залгуурын хувиргагч
- C) Толь
- D) Цонх
Зөв хариулт: B
Тайлбар: Adapter нь нийцдэггүй хоёр интерфейсийг холбодог — яг залгуурын хувиргагч шиг. Монгол залгуурыг Европын розеткад тохируулдаг.
Тест 14
Facade паттерны зорилго юу вэ?
- A) Шинэ функц нэмэх
- B) Нарийн системд хялбар, ганцхан интерфейс хангах
- C) Объект хуулбарлах
- D) Алгоритм солих
Зөв хариулт: B
Тайлбар: Facade нь нарийн дэд системүүдийг далдалж, клиентэд хялбар, ганцхан интерфейс хангадаг. Зочид буудлын ресепшн шиг — бүх зүйлийг нэг цэгээс зохион байгуулна.
Тест 15
Decorator паттерн юу хийдэг вэ?
- A) Объектыг устгах
- B) Объектод шинэ функц динамикаар давхарлаж нэмэх
- C) Объект үүсгэх
- D) Объектын төлөвийг хадгалах
Зөв хариулт: B
Тайлбар: Decorator нь объектод шинэ чадварыг динамикаар нэмдэг. Кофенд сүү, чихэр нэмдэг шиг — давхарлаж чимэглэнэ.
Тест 16
Decorator ба Inheritance-ийн ялгаа юу вэ?
- A) Ялгаагүй, нэг зүйл
- B) Decorator нь ажиллах үед динамикаар, Inheritance нь компайлын үед статикаар шийдэгддэг
- C) Inheritance нь илүү уян хатан
- D) Decorator нь илүү хурдан
Зөв хариулт: B
Тайлбар: Inheritance нь компайлын үед тодорхойлогддог (статик). Decorator нь ажиллах үед (runtime) объектод функц нэмэх боломж олгодог (динамик) → Илүү уян хатан.
Тест 17
Proxy паттерны зорилго юу вэ?
- A) Объектыг өөрчлөх
- B) Объектод хандалтыг хянах, нэмэлт логик нэмэх
- C) Шинэ класс үүсгэх
- D) Тест бичих
Зөв хариулт: B
Тайлбар: Proxy нь бодит объектын орлуулагч бөгөөд хандалтыг хянах (аюулгүй байдал), хойшлуулах (lazy loading), нэмэлт логик (logging) нэмэх зэрэгт ашиглагддаг.
Тест 18
Observer паттерныг амьдрал дээр юутай зүйрлэж болох вэ?
- A) Ресторанд хоол захиалах
- B) YouTube суваг дагах (subscribe)
- C) Номын сан дахь ном хайх
- D) Тоглоом тоглох
Зөв хариулт: B
Тайлбар: Observer = YouTube subscribe. Шинэ видео нийтлэгдэхэд бүх дагагчдад автоматаар мэдэгдэнэ. Subject (суваг) ба Observer (дагагч) хоорондын "нэг-олон" харилцаа.
Тест 19
Strategy паттерн юу хийдэг вэ?
- A) Объект үүсгэх
- B) Алгоритмыг ажиллах үед сонгож, солих боломж олгох
- C) Объектыг хуулбарлах
- D) Объект устгах
Зөв хариулт: B
Тайлбар: Strategy нь ижил зорилготой олон алгоритмыг тодорхойлж, ажиллах үед тэдгээрийг сонгох, солих боломж олгодог. Ажил руу явах олон арга шиг.
Тест 20
Template Method паттерн юу хийдэг вэ?
- A) Алгоритмын араг ясыг тодорхойлж, нарийн алхмуудыг дэд класст шилжүүлэх
- B) Объект устгах
- C) Интерфейс үүсгэх
- D) Мэдээллийн санд холбогдох
Зөв хариулт: A
Тайлбар: Template Method нь алгоритмын ерөнхий бүтцийг (араг яс) суурь класст тодорхойлж, зарим алхмуудыг дэд классуудад хэрэгжүүлэхийг шилжүүлдэг. Бууз, хуушуурыг хийх ерөнхий дараалал ижил — нарийн нь өөр.
Тест 21
Command паттерн юу хийдэг вэ?
- A) Кодыг оновчлох
- B) Хүсэлтийг объект болгож хадгалах, дараалалд оруулах, буцаах (undo)
- C) Өгөгдөл шифрлэх
- D) Тест автоматжуулах
Зөв хариулт: B
Тайлбар: Command нь хүсэлтийг объект болгож капсулжуулдаг. Ингэснээр хүсэлтийг дараалалд оруулах, хадгалах, буцаах (undo/redo) боломжтой болдог.
Тест 22
Дараах аль нь Creational Pattern вэ?
- A) Observer
- B) Adapter
- C) Singleton
- D) Strategy
Зөв хариулт: C
Тайлбар: Singleton нь Creational (бүтээх) паттерн. Observer, Strategy нь Behavioral, Adapter нь Structural паттерн.
Тест 23
Дараах аль нь Structural Pattern вэ?
- A) Factory
- B) Facade
- C) Observer
- D) Command
Зөв хариулт: B
Тайлбар: Facade нь Structural (бүтцийн) паттерн. Factory нь Creational, Observer ба Command нь Behavioral.
Тест 24
Дараах аль нь Behavioral Pattern вэ?
- A) Builder
- B) Proxy
- C) Iterator
- D) Singleton
Зөв хариулт: C
Тайлбар: Iterator нь Behavioral (зан төлөвийн) паттерн. Builder, Singleton нь Creational, Proxy нь Structural.
Тест 25
Singleton-ий "Lazy initialization" гэж юу вэ?
- A) Instance-ийг програм эхлэхэд үүсгэх
- B) Instance-ийг анх удаа дуудахад л үүсгэх
- C) Instance-ийг хэзээ ч үүсгэхгүй
- D) Олон instance үүсгэх
Зөв хариулт: B
Тайлбар: Lazy initialization = "залхуу эхлүүлэлт". Instance-ийг анх удаа
getInstance()дуудахад л үүсгэнэ — шаардлагагүй бол нөөц зарцуулахгүй.
Тест 26
Abstract Factory ба Factory Method-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Abstract Factory нь хамааралтай объектуудын ГЭР БҮЛИЙГ, Factory Method нь ганц объект үүсгэдэг
- C) Factory Method нь илүү нарийн
- D) Abstract Factory нь илүү хурдан
Зөв хариулт: B
Тайлбар: Factory Method нь ганц объект үүсгэхэд зориулагдсан. Abstract Factory нь хамааралтай объектуудын гэр бүлийг (жишээ нь: модерн ширээ + модерн сандал + модерн тавиур) нэг дор үүсгэдэг.
Тест 27
Bridge паттерн юу хийдэг вэ?
- A) Хоёр системийг холбох
- B) Хийсвэрлэлийг хэрэгжүүлэлтээс салгаж тус тусдаа хөгжүүлэх
- C) Объектыг устгах
- D) Алдааг засах
Зөв хариулт: B
Тайлбар: Bridge нь хийсвэрлэл (abstraction) ба хэрэгжүүлэлт (implementation)-ийг салгаж, тус тусдаа хөгжүүлэх боломж олгодог. ТВ-ийн пульт (хийсвэрлэл) ба ТВ (хэрэгжүүлэлт) тусдаа.
Тест 28
Composite паттерн юу хийдэг вэ?
- A) Объектуудыг мод (tree) бүтцэд зохион байгуулах
- B) Объектыг хуулбарлах
- C) Алгоритм солих
- D) Интерфейс тодорхойлох
Зөв хариулт: A
Тайлбар: Composite нь объектуудыг мод (tree) бүтцэд зохион байгуулж, ганц объект, бүлэг объект аль алиныг нь нэг интерфейсээр ашиглах боломж олгодог. Файлын систем: фолдер дотор файл ба фолдер.
Тест 29
Flyweight паттерны зорилго юу вэ?
- A) Програмыг хурдасгах
- B) Олон ижил объектын нийтлэг өгөгдлийг хуваалцуулж санах ойг хэмнэх
- C) Объектыг устгах
- D) Шинэ функц нэмэх
Зөв хариулт: B
Тайлбар: Flyweight нь олон тооны жижиг, ижил объектуудын нийтлэг (intrinsic) өгөгдлийг хуваалцуулж санах ойг хэмнэдэг. Тоглоомд 10000 мод ижил бүтэцтэй — зүгээр байрлал нь өөр.
Тест 30
State паттерн юу хийдэг вэ?
- A) Объектын төлөвийг хадгалах
- B) Объект дотоод төлөвөөс хамаарч зан төлөвөө өөрчлөх
- C) Шинэ объект үүсгэх
- D) Алгоритм оновчлох
Зөв хариулт: B
Тайлбар: State паттерн нь объектын дотоод төлөв өөрчлөгдөхөд зан төлөвөө автоматаар өөрчлөх боломж олгодог. Гар утас: дуугүй горимд дуугардаггүй, чимээтэй горимд дуугардаг.
Тест 31
Iterator паттерн юу хийдэг вэ?
- A) Объектыг хуулбарлах
- B) Цуглуулгын элементүүдийг дотоод бүтцийг далдалж дараалуулан хандах
- C) Алдаа засах
- D) Интерфейс үүсгэх
Зөв хариулт: B
Тайлбар: Iterator нь цуглуулгын (ArrayList, LinkedList, Tree) элементүүдэд дотоод бүтцийг мэдэхгүйгээр дараалуулан хандах боломж олгодог. TV-ийн суваг солигч шиг.
Тест 32
Mediator паттерн юу хийдэг вэ?
- A) Объектуудын шууд харилцааг зогсоож, нэг зуучлагчаар дамжуулдаг
- B) Объект үүсгэх
- C) Алгоритм оновчлох
- D) Тест бичих
Зөв хариулт: A
Тайлбар: Mediator нь олон объектын хоорондын шууд харилцааг зогсоож, бүх харилцааг нэг зуучлагч (mediator) объектоор дамжуулдаг. Нисэх буудлын удирдах цамхаг шиг — онгоцнууд хоорондоо биш, цамхагтай ярьдаг.
Тест 33
Memento паттерн юу хийдэг вэ?
- A) Объектын өмнөх төлөвийг хадгалж, хэрэгтэй үед сэргээх
- B) Объект устгах
- C) Шинэ интерфейс нэмэх
- D) Алгоритм солих
Зөв хариулт: A
Тайлбар: Memento нь объектын дотоод төлөвийг (state) хадгалж, дараа нь буцааж сэргээх (undo) боломж олгодог. Тоглоомын "save point" шиг — алдвал өмнөх хадгалсан цэгээс дахин эхэлнэ.
Тест 34
Chain of Responsibility паттерн юу хийдэг вэ?
- A) Хүсэлтийг гинжин хэлхээгээр дамжуулж, тохирох зохицуулагч олтол дамжуулдаг
- B) Объект үүсгэх
- C) Объектыг хуулбарлах
- D) Мэдээллийн санд хадгалах
Зөв хариулт: A
Тайлбар: Chain of Responsibility нь хүсэлтийг зохицуулагчдын гинжин хэлхээгээр дамжуулдаг. Зохицуулагч бүр хүсэлтийг шийднэ, эсвэл дараагийнхдаа дамжуулна. Байгууллагад өргөдөл дамжуулах шиг.
Тест 35
Visitor паттерн юу хийдэг вэ?
- A) Объектын бүтцийг өөрчлөхгүйгээр шинэ үйлдэл нэмэх
- B) Объект устгах
- C) Объект хуулбарлах
- D) Интерфейс тодорхойлох
Зөв хариулт: A
Тайлбар: Visitor нь одоо байгаа класс бүтцийг ямар ч өөрчлөлтгүйгээр шинэ үйлдэл (алгоритм) нэмэх боломж олгодог. Open/Closed зарчимтай нийцтэй.
Тест 36
Interpreter паттерн юу хийдэг вэ?
- A) Код хөрвүүлэх
- B) Хэлний дүрэм тодорхойлж, өгүүлбэрийг тайлбарлах
- C) Объект үүсгэх
- D) Алгоритм оновчлох
Зөв хариулт: B
Тайлбар: Interpreter нь хэлний grammar (дүрэм) тодорхойлж, тэр дүрмийн дагуу өгүүлбэрийг (expression) тайлбарладаг. SQL query задлалт, математикийн илэрхийлэл тайлах зэрэгт хэрэглэгддэг.
Тест 37
SOLID-ийн "S" юу гэсэн үг вэ?
- A) Secure — Аюулгүй
- B) Single Responsibility — Нэг үүрэг
- C) Simple — Энгийн
- D) Static — Статик
Зөв хариулт: B
Тайлбар: S = Single Responsibility Principle. Нэг класс зөвхөн НЭГ үүрэгтэй байх ёстой, нэг л шалтгаанаар өөрчлөгдөх ёстой.
Тест 38
SOLID-ийн "O" юу гэсэн үг вэ?
- A) Object — Объект
- B) Open/Closed — Нээлттэй/Хаалттай
- C) Optimal — Оновчтой
- D) Override — Дахин тодорхойлох
Зөв хариулт: B
Тайлбар: O = Open/Closed Principle. Класс ӨРГӨТГӨХӨД нээлттэй, ӨӨРЧЛӨХӨД хаалттай байх ёстой. Decorator, Strategy паттернууд үүнийг хэрэгжүүлдэг.
Тест 39
SOLID-ийн "L" юу гэсэн үг вэ?
- A) Linked — Холбогдсон
- B) Liskov Substitution — Лисковын орлуулалт
- C) Loose — Сул
- D) Limited — Хязгаарлагдсан
Зөв хариулт: B
Тайлбар: L = Liskov Substitution Principle. Дэд класс нь эцэг классыг ЯМ ЧА ХЯЗГААРГҮЙ орлож чадах ёстой. Програм зөв ажиллагаагаа алдахгүй.
Тест 40
SOLID-ийн "I" юу гэсэн үг вэ?
- A) Inheritance — Удамшил
- B) Interface Segregation — Интерфейс тусгаарлалт
- C) Implementation — Хэрэгжүүлэлт
- D) Integration — Нэгтгэл
Зөв хариулт: B
Тайлбар: I = Interface Segregation Principle. Клиент ашигладаггүй методуудаас хамаарах ёсгүй — том интерфейсийг жижиг, тусгай зориулалтын интерфейсүүдэд хуваах.
Тест 41
SOLID-ийн "D" юу гэсэн үг вэ?
- A) Data — Өгөгдөл
- B) Dependency Inversion — Хамааралын урвуу
- C) Dynamic — Динамик
- D) Design — Дизайн
Зөв хариулт: B
Тайлбар: D = Dependency Inversion Principle. Дээд түвшний модуль доод түвшнийхээс хамаарах ёсгүй — хоёулаа ХИЙСВЭРЛЭЛЭЭС хамаарах ёстой.
Тест 42
"Composition over Inheritance" зарчим юу гэсэн үг вэ?
- A) Удамшлыг хэзээ ч ашиглахгүй
- B) Боломжтой бол удамшлын оронд бүтэц (composition) ашиглах
- C) Интерфейс ашиглахгүй
- D) Нэг классаас олон удамшил авах
Зөв хариулт: B
Тайлбар: GoF номонд "Удамшлын оронд бүтэц (composition) илүүд үз" гэж зөвлөсөн. Composition нь илүү уян хатан — ажиллах үед зан төлөвөө өөрчилж чаддаг. Strategy, Decorator нь composition ашигладаг.
Тест 43
"Program to an interface, not an implementation" зарчим юу гэсэн үг вэ?
- A) Зөвхөн интерфейс ашиглах
- B) Бодит класс биш, интерфейс/хийсвэр төрлөөс хамаарах
- C) Implementation код бичихгүй
- D) Зөвхөн abstract class ашиглах
Зөв хариулт: B
Тайлбар: GoF-ийн гол зарчим. Хувьсагчийн төрлийг бодит класс биш, интерфейс/хийсвэр класс болгох → Хэрэгжүүлэлтийг амархан солих боломжтой.
Тест 44
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
class Logger {
private static Logger instance;
private Logger() { }
public static Logger getInstance() {
if (instance == null) instance = new Logger();
return instance;
}
}
- A) Factory
- B) Singleton
- C) Observer
- D) Strategy
Зөв хариулт: B
Тайлбар: Private constructor + static instance + getInstance() → Singleton паттерн. Зөвхөн нэг Logger объект үүснэ.
Тест 45
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
interface Animal { void speak(); }
class Dog implements Animal { public void speak() { System.out.println("Woof!"); } }
class Cat implements Animal { public void speak() { System.out.println("Meow!"); } }
class AnimalFactory {
public static Animal create(String type) {
if (type.equals("dog")) return new Dog();
return new Cat();
}
}
- A) Singleton
- B) Observer
- C) Factory Method
- D) Decorator
Зөв хариулт: C
Тайлбар: String параметрээр бодит классыг сонгож объект үүсгэж байна → Factory Method паттерн.
Тест 46
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
- A) Factory
- B) Builder
- C) Decorator
- D) Singleton
Зөв хариулт: C
Тайлбар: Объектыг давхарлаж (wrap) шинэ функц нэмж байна → Decorator паттерн. Кофенд сүү, чихэр нэмэж байгаа шиг.
Тест 47
Observer паттерн дахь Subject юу хийдэг вэ?
- A) Мэдэгдэл хүлээн авах
- B) Мэдэгдэл илгээх, Observer-уудыг бүртгэх/хасах
- C) Объект үүсгэх
- D) Алгоритм солих
Зөв хариулт: B
Тайлбар: Subject нь Observer-уудыг бүртгэж (subscribe), хасаж (unsubscribe), төлөв өөрчлөгдөхөд бүгдэд мэдэгдэл илгээдэг (notify).
Тест 48
Strategy паттерн дахь Context юу хийдэг вэ?
- A) Алгоритмыг хэрэгжүүлэх
- B) Стратегийг хадгалж, ашиглах
- C) Шинэ стратеги үүсгэх
- D) Стратегийг устгах
Зөв хариулт: B
Тайлбар: Context нь Strategy объектын ссылкийг хадгалж, ажиллах үед тухайн стратегийн алгоритмыг дуудна. Стратегийг runtime-д солих боломжтой.
Тест 49
Паттерн хэрэглэх хамгийн том аюул юу вэ?
- A) Код хурдасдаг
- B) Over-engineering — шаардлагагүй нарийн төвөгтэй шийдэл хэрэглэх
- C) Код богиносдог
- D) Тест бичих хялбар болдог
Зөв хариулт: B
Тайлбар: Over-engineering нь хамгийн том аюул. Энгийн if/else-ээр шийдэх асуудалд Strategy паттерн хэрэглэх нь кодыг шаардлагагүй нарийн болгож, ойлгоход хүндрүүлнэ.
Тест 50
"Design for Change" зарчим юу гэсэн үг вэ?
- A) Код байнга өөрчлөх
- B) Ирээдүйн өөрчлөлтийг урьдчилан тооцож дизайнлах
- C) Кодыг устгах
- D) Тест бичихгүй
Зөв хариулт: B
Тайлбар: GoF: "Систем дизайнлахдаа зайлшгүй ирэх өөрчлөлтийг урьдчилан тооцох ёстой." Паттернууд нь энэ зарчмыг хэрэгжүүлдэг — өөрчлөлтөд нээлттэй дизайн.
Тест 51
Singleton-ий multi-threaded орчин дахь асуудал юу вэ?
- A) Хэт удаан ажилладаг
- B) Хоёр thread нэг зэрэг getInstance() дуудвал хоёр instance үүсч болно
- C) Ямар ч асуудалгүй
- D) Компайл хийгдэхгүй
Зөв хариулт: B
Тайлбар: Хоёр thread нэг зэрэг
if (instance == null)шалгавал хоёулааtrueгэж хариулж, хоёр instance үүсгэж болно. Шийдэл:synchronized, double-checked locking, эсвэл enum Singleton.
Тест 52
Thread-safe Singleton хийх хамгийн найдвартай арга аль нь вэ?
- A) Synchronized метод
- B) Double-checked locking
- C) Enum Singleton
- D) Lazy initialization
Зөв хариулт: C
Тайлбар: Java-д
enum Singletonхамгийн найдвартай — JVM serialization, reflection, thread safety бүгдийг автоматаар хангадаг. Joshua Bloch (Effective Java) зөвлөсөн.
Тест 53
Дараах аль нь Singleton-ий жишээ вэ (бодит амьдрал)?
- A) Оюутан
- B) Мэдээллийн сангийн холболтын менежер
- C) Машин
- D) Ном
Зөв хариулт: B
Тайлбар: Мэдээллийн сангийн холболтын менежер нь зөвхөн нэг байх ёстой — олон холболт нээвэл нөөц дуусна. Мөн Logger, Configuration Manager зэрэг нь Singleton.
Тест 54
Factory Method ямар SOLID зарчимтай хамгийн нягт холбоотой вэ?
- A) Single Responsibility
- B) Open/Closed
- C) Liskov Substitution
- D) Interface Segregation
Зөв хариулт: B
Тайлбар: Factory Method нь Open/Closed зарчимтай нягт холбоотой — шинэ бүтээгдэхүүн нэмэхэд одоо байгаа Factory кодыг өөрчлөхгүйгээр (хаалттай) шинэ дэд класс нэмж (нээлттэй) болно.
Тест 55
Builder паттерны build() метод юу хийдэг вэ?
- A) Builder объект үүсгэх
- B) Эцсийн бүтээгдэхүүн (final product) объект үүсгэж буцаах
- C) Параметр нэмэх
- D) Объект устгах
Зөв хариулт: B
Тайлбар:
build()метод нь Builder-д хуримтлагдсан бүх параметраар эцсийн объектыг үүсгэж буцаадаг. Бургер бэлтгэж дууссаны дараа таваглаж өгөх шиг.
Тест 56
Adapter паттерны хоёр хэлбэр аль нь вэ?
- A) Singleton ба Factory
- B) Class Adapter ба Object Adapter
- C) Static ба Dynamic
- D) Simple ба Complex
Зөв хариулт: B
Тайлбар: Class Adapter нь удамшил (inheritance) ашигладаг, Object Adapter нь бүтэц (composition) ашигладаг. Object Adapter илүү уян хатан — "Composition over Inheritance" зарчимтай нийцтэй.
Тест 57
Facade ба Adapter-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Facade нь нарийн системд хялбар интерфейс, Adapter нь нийцдэггүй интерфейсийг холбодог
- C) Adapter нь илүү хялбар
- D) Facade нь объект үүсгэдэг
Зөв хариулт: B
Тайлбар: Facade = нарийн системийг далдалж хялбар интерфейс хангах. Adapter = хоёр нийцдэггүй интерфейсийг холбох. Зорилго өөр.
Тест 58
Decorator паттерн ямар интерфейсийг хэрэгжүүлдэг вэ?
- A) Өөрийн тусгай интерфейс
- B) Чимэглэж буй объекттой ижил интерфейс
- C) Ямар ч интерфейс хэрэгжүүлдэггүй
- D) Java.io интерфейс
Зөв хариулт: B
Тайлбар: Decorator нь чимэглэж буй объекттой ижил интерфейс хэрэгжүүлнэ → Клиент ялгаа мэдэхгүй. Java I/O: BufferedReader нь Reader-тэй ижил интерфейстэй.
Тест 59
Java-ийн I/O системд ямар паттерн ашиглагддаг вэ?
- A) Singleton
- B) Decorator
- C) Factory
- D) Observer
Зөв хариулт: B
Тайлбар: Java I/O нь Decorator паттерн ашигладаг:
new BufferedReader(new InputStreamReader(new FileInputStream("file.txt")))— давхарлаж функц нэмж байна.
Тест 60
Proxy паттерны "Lazy Loading" гэж юу вэ?
- A) Объектыг хурдан ачаалах
- B) Объектыг анх хэрэгтэй болоход л үүсгэж ачаалах
- C) Объектыг устгах
- D) Объектыг хуулбарлах
Зөв хариулт: B
Тайлбар: Lazy Loading = "Залхуу ачаалалт". Proxy нь бодит объектыг анх дуудахад л ачаална — шаардлагагүй бол нөөц зарцуулахгүй. Вэбсайтын зураг lazy load хийх шиг.
Тест 61
Observer паттерн дахь "push" ба "pull" загварын ялгаа юу вэ?
- A) Ялгаагүй
- B) Push: Subject мэдээлэл илгээдэг, Pull: Observer өөрөө мэдээлэл авдаг
- C) Push нь удаан, Pull нь хурдан
- D) Pull нь илүү хялбар
Зөв хариулт: B
Тайлбар: Push загвар: Subject бүх мэдээллийг Observer-уудад шууд илгээдэг. Pull загвар: Subject зөвхөн "өөрчлөлт байна" гэж мэдэгдэж, Observer-ууд хэрэгтэй мэдээллээ өөрсдөө татдаг.
Тест 62
Strategy ба State паттерны ялгаа юу вэ?
- A) Ялгаагүй, нэг зүйл
- B) Strategy нь клиент стратеги сонгодог, State нь объект өөрөө төлөвөө өөрчилдөг
- C) State нь илүү хурдан
- D) Strategy нь илүү энгийн
Зөв хариулт: B
Тайлбар: Strategy: клиент алгоритмыг гаднаас сонгоно. State: объект дотоод төлөвөө автоматаар өөрчлөх → зан төлөв автоматаар өөрчлөгддөг.
Тест 63
Template Method дахь final түлхүүр үг юу хийдэг вэ?
- A) Хувьсагчийг тогтмол болгох
- B) Template method-ийг дэд класс дахин тодорхойлохоос хамгаалах
- C) Класс удамшлыг хориглох
- D) Объект үүсгэхийг хориглох
Зөв хариулт: B
Тайлбар: Template method-ийг
finalболговол дэд класс АЛГОРИТМЫН ДАРААЛЛЫГ өөрчилж чадахгүй — зөвхөн тодорхой алхмуудыг л дахин тодорхойлно. Алгоритмын бүтэц хамгаалагдана.
Тест 64
Creational паттернуудын ГОЛ зорилго юу вэ?
- A) Код оновчлох
- B) Объект үүсгэх процессыг хийсвэрлэж, системийг уян хатан болгох
- C) Тест бичих
- D) Алдаа засах
Зөв хариулт: B
Тайлбар: Creational паттернууд объект ЯАЖЕ үүсгэхийг далдалж, системийг бодит классуудаас хамааралгүй болгодог → Шинэ төрөл нэмэхэд код бага өөрчлөгдөнө.
Тест 65
Structural паттернуудын ГОЛ зорилго юу вэ?
- A) Объект үүсгэх
- B) Класс, объектуудыг уян хатан, үр ашигтай том бүтцэд нэгтгэх
- C) Алгоритм тодорхойлох
- D) Мэдээллийн сан удирдах
Зөв хариулт: B
Тайлбар: Structural паттернууд нь объектуудыг том бүтцэд зохион байгуулахдаа уян хатан, засвар хялбар байлгахыг зорьдог.
Тест 66
Behavioral паттернуудын ГОЛ зорилго юу вэ?
- A) Объект үүсгэх
- B) Бүтэц зохион байгуулах
- C) Объектуудын хоорондын харилцааг уян хатан, loose coupling-тэй болгох
- D) Мэдээллийн сан удирдах
Зөв хариулт: C
Тайлбар: Behavioral паттернууд нь объектуудын хоорондын харилцааг зохицуулж, loose coupling хангаж, функцийг хялбар өргөтгөх боломж олгодог.
Тест 67
Кристофер Александерийн анхны "A Pattern Language" ном ямар салбарт зориулагдсан вэ?
- A) Програм хангамж
- B) Барилга, хот байгуулалт
- C) Математик
- D) Эдийн засаг
Зөв хариулт: B
Тайлбар: Кристофер Александер 1977 онд "A Pattern Language: Towns, Buildings, Construction" номыг бичсэн — барилга, хот байгуулалтад зориулсан. GoF нар 1995 онд энэ санааг програм хангамжид авчирсан.
Тест 68
GoF-ийн "Design Patterns" ном хэдэн онд хэвлэгдсэн вэ?
- A) 1977
- B) 1985
- C) 1995
- D) 2005
Зөв хариулт: C
Тайлбар: "Design Patterns: Elements of Reusable Object-Oriented Software" ном 1995 онд хэвлэгдсэн. 1977 он нь Кристофер Александерийн барилгын "A Pattern Language" ном хэвлэгдсэн он.
Тест 69
Паттерны 3 бүрэлдэхүүн хэсэг аль нь вэ?
- A) Нэр, Код, Тест
- B) Асуудал, Контекст, Шийдэл
- C) Класс, Интерфейс, Объект
- D) Оролт, Процесс, Гаралт
Зөв хариулт: B
Тайлбар: Паттерн бүр гурван зүйлийг тодорхойлдог: Асуудал (Problem) — юу шийдэх, Контекст (Context) — ямар нөхцөлд, Шийдэл (Solution) — хэрхэн шийдэх.
Тест 70
Дараах аль нь Creational Pattern БИШ вэ?
- A) Singleton
- B) Builder
- C) Decorator
- D) Prototype
Зөв хариулт: C
Тайлбар: Decorator нь Structural (бүтцийн) паттерн. Singleton, Builder, Prototype нь Creational (бүтээх) паттернууд.
Тест 71
Дараах аль нь Structural Pattern БИШ вэ?
- A) Adapter
- B) Observer
- C) Facade
- D) Proxy
Зөв хариулт: B
Тайлбар: Observer нь Behavioral (зан төлөвийн) паттерн. Adapter, Facade, Proxy нь Structural (бүтцийн) паттернууд.
Тест 72
Дараах аль нь Behavioral Pattern БИШ вэ?
- A) Strategy
- B) Factory
- C) Command
- D) Template Method
Зөв хариулт: B
Тайлбар: Factory нь Creational (бүтээх) паттерн. Strategy, Command, Template Method нь Behavioral (зан төлөвийн) паттернууд.
Тест 73
Creational паттернуудын тоо хэд вэ (GoF)?
- A) 3
- B) 5
- C) 7
- D) 11
Зөв хариулт: B
Тайлбар: GoF-д 5 Creational паттерн: Singleton, Factory Method, Abstract Factory, Builder, Prototype.
Тест 74
Structural паттернуудын тоо хэд вэ (GoF)?
- A) 3
- B) 5
- C) 7
- D) 11
Зөв хариулт: C
Тайлбар: GoF-д 7 Structural паттерн: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy.
Тест 75
Behavioral паттернуудын тоо хэд вэ (GoF)?
- A) 5
- B) 7
- C) 9
- D) 11
Зөв хариулт: D
Тайлбар: GoF-д 11 Behavioral паттерн: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.
Тест 76
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
public final void prepareMeal() {
prepareIngredients();
cook();
serve();
}
abstract void prepareIngredients();
abstract void cook();
- A) Strategy
- B) Template Method
- C) Factory
- D) Observer
Зөв хариулт: B
Тайлбар:
finalметодод алгоритмын дараалал тодорхойлж, abstract метод дэд класст шилжүүлж байна → Template Method паттерн.
Тест 77
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
interface PaymentStrategy { void pay(int amount); }
class CreditCard implements PaymentStrategy { ... }
class QPay implements PaymentStrategy { ... }
class Cart { void setPaymentStrategy(PaymentStrategy s) { ... } }
- A) Observer
- B) Strategy
- C) Singleton
- D) Factory
Зөв хариулт: B
Тайлбар: Интерфейсээр олон алгоритм тодорхойлж, Context (Cart) класст runtime-д стратеги сонгож солих → Strategy паттерн.
Тест 78
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
channel.subscribe(new User("Бат"));
channel.subscribe(new User("Болд"));
channel.publishVideo("Шинэ видео");
- A) Factory
- B) Singleton
- C) Observer
- D) Builder
Зөв хариулт: C
Тайлбар: subscribe() дагагч бүртгэж, publishVideo() дуудахад бүх дагагчдад мэдэгдэж байна → Observer паттерн. YouTube subscribe шиг.
Тест 79
Дараах кодонд ямар паттерн ашиглагдаж байна вэ?
Student s = new Student.Builder("Бат", 20)
.email("bat@email.com")
.phone("99112233")
.build();
- A) Singleton
- B) Factory
- C) Builder
- D) Prototype
Зөв хариулт: C
Тайлбар: Алхам алхмаар параметр нэмж,
build()метод эцсийн объект үүсгэж байна → Builder паттерн.
Тест 80
Singleton-ий "Eager initialization" гэж юу вэ?
- A) Instance-ийг анх удаа дуудахад үүсгэх
- B) Instance-ийг класс ачаалагдахад шууд үүсгэх
- C) Instance-ийг хэзээ ч үүсгэхгүй
- D) Instance-ийг устгах
Зөв хариулт: B
Тайлбар: Eager initialization = "Эрт эхлүүлэлт".
private static final Instance = new Instance();— класс ачаалагдмагц үүсгэдэг. Thread-safe гэхдээ хэрэглэхгүй байсан ч нөөц зарцуулна.
Тест 81
Proxy-ийн гурван нийтлэг төрөл аль нь вэ?
- A) Fast, Medium, Slow
- B) Virtual Proxy, Protection Proxy, Remote Proxy
- C) Simple, Complex, Advanced
- D) Input, Process, Output
Зөв хариулт: B
Тайлбар: Virtual Proxy (lazy loading), Protection Proxy (хандалт хянах), Remote Proxy (алсын объект орлуулах) — 3 нийтлэг төрөл.
Тест 82
MVC (Model-View-Controller) дахь View ямар паттерн ашигладаг вэ?
- A) Singleton
- B) Factory
- C) Observer
- D) Builder
Зөв хариулт: C
Тайлбар: MVC-д View нь Model-ийг ажигладаг (observe). Model өөрчлөгдөхөд View автоматаар шинэчлэгддэг → Observer паттерн.
Тест 83
Дараах аль нь паттерн ашиглахын ДАВУУ ТАЛ вэ?
- A) Код нарийн болдог
- B) Хөгжүүлэгчид хоорондоо нийтлэг хэлээр ярьдаг
- C) Компайл удаашралдаг
- D) Санах ой ихээр зарцуулдаг
Зөв хариулт: B
Тайлбар: Паттерн мэддэг хөгжүүлэгчид "Энд Observer хэрэгл" гэхэд бүгд юу хэлж байгааг ойлгодог → нийтлэг хэл (common vocabulary).
Тест 84
Singleton-д getInstance() метод яагаад static байдаг вэ?
- A) Компайлер шаарддаг
- B) Объект үүсгэхгүйгээр (new хийхгүйгээр) класс нэрээр дуудах боломжтой болгох
- C) Хурдыг нэмэгдүүлэх
- D) Thread safety хангах
Зөв хариулт: B
Тайлбар: Constructor private → гаднаас new хийж чадахгүй. Тиймээс
staticметод хэрэглэнэ —ClassName.getInstance()гэж объектгүйгээр дуудна.
Тест 85
Abstract Factory паттерныг амьдрал дээр юутай зүйрлэж болох вэ?
- A) Ресторанд хоол захиалах
- B) Тавилга дэлгүүрийн каталог — нэг загвар сонговол бүх тавилга тэр загвараар
- C) Машин засварлах
- D) Ном уншах
Зөв хариулт: B
Тайлбар: Abstract Factory = Тавилга каталог. "Модерн" загвар сонговол ширээ, сандал, тавиур бүгд модерн загвараар үүснэ. Хамааралтай объектуудын гэр бүл.
Тест 86
Дараах аль нь "Loose Coupling" хангадаг паттерн вэ?
- A) Singleton
- B) Observer
- C) Builder
- D) Prototype
Зөв хариулт: B
Тайлбар: Observer нь Subject ба Observer хоорондын loose coupling хангадаг — Subject нь Observer-уудын бодит классыг мэдэх шаардлагагүй, зөвхөн интерфейсийг мэднэ.
Тест 87
GoF номонд Encapsulation-ий аль хэлбэрийг онцлон зөвлөсөн вэ?
- A) Өгөгдлийн encapsulation
- B) Өөрчлөгдөж болох зүйлийг encapsulate хийх (encapsulate what varies)
- C) Бүх зүйлийг encapsulate хийх
- D) Зөвхөн private хувьсагч ашиглах
Зөв хариулт: B
Тайлбар: GoF: "Encapsulate what varies" — Өөрчлөгдөж болох зүйлийг тусгаарла. Strategy нь алгоритмыг, Factory нь объект үүсгэх логикийг тусгаарладаг.
Тест 88
Builder паттерны method chaining гэж юу вэ?
- A) Олон метод нэг зэрэг дуудах
- B) Метод бүр
thisбуцааж, дараалуулан дуудах боломж олгох - C) Метод хоорондоо дуудах
- D) Рекурсив дуудлага
Зөв хариулт: B
Тайлбар: Method chaining: метод бүр
return thisхийснээр.email("...").phone("...").build()гэж дараалуулан бичих боломжтой → Код уншихад ойлгомжтой.
Тест 89
Flyweight паттерн дахь intrinsic state гэж юу вэ?
- A) Объект бүрт өөр утгатай мэдээлэл
- B) Олон объектод нийтлэг, хуваалцдаг мэдээлэл
- C) Объектын нэр
- D) Объектын ID
Зөв хариулт: B
Тайлбар: Intrinsic state = Дотоод (нийтлэг) төлөв — олон объект хуваалцдаг. Extrinsic state = Гадаад (тусгай) төлөв — объект бүрт өөр. Тоглоомд: модны текстур (intrinsic), байрлал (extrinsic).
Тест 90
Flyweight паттерн дахь extrinsic state гэж юу вэ?
- A) Олон объектод нийтлэг мэдээлэл
- B) Объект бүрт тусгай, өөр утгатай мэдээлэл
- C) Объектын класс нэр
- D) Компайлын тохиргоо
Зөв хариулт: B
Тайлбар: Extrinsic state нь объект бүрт ТУСГАЙ мэдээлэл. Тоглоомд: мод бүрийн байрлал (x, y координат) нь extrinsic — мод бүрт өөр.
Тест 91
Composite паттерн дахь Leaf ба Composite-ийн ялгаа юу вэ?
- A) Ялгаагүй
- B) Leaf нь хүүхэдгүй, Composite нь хүүхэдтэй
- C) Composite нь жижиг, Leaf нь том
- D) Leaf нь нарийн, Composite нь энгийн
Зөв хариулт: B
Тайлбар: Leaf = навч (хүүхэдгүй, жишээ нь файл). Composite = салаа (хүүхэдтэй, жишээ нь фолдер). Хоёулаа ижил интерфейстэй → Нэг мэтээр ашиглана.
Тест 92
Дизайн паттерн ашиглахгүй байх ёстой тохиолдол аль нь вэ?
- A) Давтагддаг нарийн асуудал тулгарсан
- B) Энгийн if/else-ээр шийдэгдэх бага асуудал
- C) Том системийн архитектур дизайнлаж байх
- D) Багийн харилцааг сайжруулах
Зөв хариулт: B
Тайлбар: Энгийн асуудалд паттерн хэрэглэх нь over-engineering. GoF: "Хамгийн энгийн шийдэл нь хамгийн сайн шийдэл. Паттерн зөвхөн нарийн төвөгтэй байдал зөвтгөгдөх үед ашиглагдах ёстой."
Тест 93
Java Collections Framework-д ямар паттерн ашиглагддаг вэ?
- A) Singleton
- B) Iterator
- C) Builder
- D) Proxy
Зөв хариулт: B
Тайлбар: Java Collections Framework нь Iterator паттерн ашигладаг.
for (String s : list)нь дотроо Iterator.hasNext(), Iterator.next() дуудаж байдаг.
Тест 94
java.util.Collections.sort() ямар паттерн ашигладаг вэ?
- A) Singleton
- B) Factory
- C) Strategy
- D) Observer
Зөв хариулт: C
Тайлбар:
Collections.sort(list, comparator)— Comparator нь Strategy паттерн. Эрэмбэлэх алгоритмыг (стратеги) параметрээр дамжуулж, runtime-д солих боломжтой.
Тест 95
java.awt ба javax.swing-д ямар паттерн ашиглагддаг вэ?
- A) Singleton
- B) Factory
- C) Observer (Event Listener)
- D) Builder
Зөв хариулт: C
Тайлбар: Java GUI framework-д event listener нь Observer паттерн. Button.addActionListener() нь Observer бүртгэж, товч дарахад бүх listener-уудад мэдэгдэнэ.
Тест 96
Polymorphism ба Strategy паттерны хамаарал юу вэ?
- A) Хамааралгүй
- B) Strategy нь Polymorphism-д суурилдаг — нэг интерфейсээр олон алгоритм дуудна
- C) Polymorphism нь Strategy-д суурилдаг
- D) Хоёулаа нэг зүйл
Зөв хариулт: B
Тайлбар: Strategy паттерн нь Polymorphism-д суурилдаг. Интерфейс (PaymentStrategy) нэг, бодит хэрэгжүүлэлт (CreditCard, QPay, Cash) олон → Runtime-д зөв хэрэгжүүлэлт дуудагддаг.
Тест 97
Singleton-ий сул тал юу вэ?
- A) Маш хурдан
- B) Глобал төлөв үүсгэдэг тул тестлэхэд хүндрэлтэй, tight coupling үүсгэж болно
- C) Хэт энгийн
- D) Олон объект үүсгэдэг
Зөв хариулт: B
Тайлбар: Singleton нь глобал төлөв (global state) үүсгэдэг → Unit тестэд mock-лоход хэцүү, классууд хоорондоо нягт холбогдож (tight coupling) болно. Тиймээс зөвхөн шаардлагатай үед ашиглах.
Тест 98
"Favor object composition over class inheritance" — энэ зарчмыг хэн хэлсэн вэ?
- A) Robert C. Martin
- B) Gang of Four (GoF)
- C) Martin Fowler
- D) Kent Beck
Зөв хариулт: B
Тайлбар: GoF-ийн "Design Patterns" номны хоёр гол зарчмын нэг: "Favor object composition over class inheritance" — Удамшлын оронд composition илүүд үз.
Тест 99
Паттерн ашиглахын давуу талуудаас аль нь БИШ вэ?
- A) Батлагдсан шийдэл
- B) Нийтлэг хэл
- C) Код автоматаар зөв болдог
- D) Дахин ашиглалт
Зөв хариулт: C
Тайлбар: Паттерн ашигласнаар код АВТОМАТААР зөв болдоггүй — паттерныг ЗӨӨВ хэрэгжүүлэх хэрэгтэй. Буруу хэрэглэвэл over-engineering үүснэ.
Тест 100
Дизайн паттернууд яагаад чухал вэ?
- A) Зөвхөн ажлын ярилцлагад хэрэгтэй
- B) Батлагдсан, дахин ашиглагдах шийдлүүд бөгөөд уян хатан, засвар хялбар, ойлгомжтой код бичихэд тусалдаг
- C) Зөвхөн том компаниуд ашигладаг
- D) Компайлер шаарддаг
Зөв хариулт: B
Тайлбар: Дизайн паттернууд нь олон жилийн туршлагаар батлагдсан шийдлүүд. Код уян хатан (flexible), засвар хялбар (maintainable), ойлгомжтой (readable) болгодог. Хөгжүүлэгчид хоорондоо нийтлэг хэлээр ярьж, илүү хурдан, чанартай програм бүтээх боломж олгодог.
📚 Ашигласан эх сурвалжууд:
- Design Patterns: Elements of Reusable Object-Oriented Software (GoF, 1995)
- Dive Into Design Patterns by Alexander Shvets
- Hands-On Design Patterns with Java by Edward Lavieri
- Steven John Metsker — Design Patterns in Java, 2nd Edition
- Vaskaran Sarcar — Java Design Patterns: A Hands-On Experience
- Software Engineering: A Modern Approach — Chapter 6: Design Patterns
- DigitalOcean — Gang of 4 Design Patterns Explained
- Head First Design Patterns by Eric Freeman & Elisabeth Robson