From 300f1a0c34676bba78a8b37cb12c641219162c01 Mon Sep 17 00:00:00 2001 From: bychevskaya Date: Mon, 10 Nov 2025 15:54:31 +0500 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=80=D0=B8=D0=BD=D0=B0=20=D0=91=D1=8B?= =?UTF-8?q?=D1=87=D0=B5=D0=B2=D1=81=D0=BA=D0=B0=D1=8F=20=D0=9F=D1=80=D0=98?= =?UTF-8?q?-201=20=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- task01/README.md | 12 +- task01/src/com/example/task01/Logger.java | 103 ++++++++++++++++++ task01/src/com/example/task01/Task01Main.java | 19 +++- .../src/com/example/task02/DiscountBill.java | 18 +++ task02/src/com/example/task02/Task02Main.java | 33 +++--- task03/src/com/example/task03/Hours.java | 30 +++++ .../src/com/example/task03/Milliseconds.java | 6 +- task03/src/com/example/task03/Minutes.java | 19 ++-- task03/src/com/example/task03/Seconds.java | 5 +- task03/src/com/example/task03/Task03Main.java | 4 + task03/src/com/example/task03/TimeUnit.java | 2 + .../src/com/example/task03/TimeUnitUtils.java | 4 + task04/README.md | 3 +- .../com/example/task04/ConsoleHandler.java | 8 ++ .../src/com/example/task04/FileHandler.java | 23 ++++ task04/src/com/example/task04/Level.java | 8 ++ task04/src/com/example/task04/Logger.java | 41 +++++++ .../src/com/example/task04/MemoryHandler.java | 21 ++++ .../com/example/task04/MessageHandler.java | 5 + .../example/task04/RotationFileHandler.java | 20 ++++ task04/src/com/example/task04/Task04Main.java | 10 ++ 21 files changed, 363 insertions(+), 31 deletions(-) create mode 100644 task01/src/com/example/task01/Logger.java create mode 100644 task02/src/com/example/task02/DiscountBill.java create mode 100644 task03/src/com/example/task03/Hours.java create mode 100644 task04/src/com/example/task04/ConsoleHandler.java create mode 100644 task04/src/com/example/task04/FileHandler.java create mode 100644 task04/src/com/example/task04/Level.java create mode 100644 task04/src/com/example/task04/Logger.java create mode 100644 task04/src/com/example/task04/MemoryHandler.java create mode 100644 task04/src/com/example/task04/MessageHandler.java create mode 100644 task04/src/com/example/task04/RotationFileHandler.java diff --git a/task01/README.md b/task01/README.md index 5e41b92c..648dd271 100644 --- a/task01/README.md +++ b/task01/README.md @@ -5,7 +5,9 @@ Требования к классу `Logger`: * Каждому экземпляру класса можно задать имя. Имя можно получить, вызвав публичный метод `String getName()`. -* В классе должен быть публичный статический метод `getLogger(String name)`, возвращающий экземпляр логгера с указанным именем. Повторый вызов с тем же аргументом должен возвращать тот же самый экземпляр, что и при первом вызове. Если продемонстрировать это кодом, то следующий код должен возвращать true: +* В классе должен быть публичный статический метод `getLogger(String name)`, возвращающий экземпляр логгера с указанным именем. +* Повторый вызов с тем же аргументом должен возвращать тот же самый экземпляр, что и при первом вызове. +* Если продемонстрировать это кодом, то следующий код должен возвращать true: ``` Logger logger1 = Logger.getLogger("test") Logger logger2 = Logger.getLogger("test") @@ -31,9 +33,13 @@ return logger1 == logger2 ``` [WARNING] 2018.07.17 09:56:32 myLogger - something weird happened ``` -* Для каждого уровня нужно добавить 2 метода. Название методов должно совпадать с уровнем (в нижнем регистре, например, error). Один метод должен принимать в качестве аргумента строку, которая должна быть выведена на экран в качестве *MESSAGE*. Второй метод должен принимать первым параметром шаблон сообщения (в любом формате, например `java.lang.String.format()` или `java.text.MessageFormat.format()` и любым количеством дополнительных аргументов, которые будут использоваться для форматирования переданной строки. +* Для каждого уровня нужно добавить 2 метода. Название методов должно совпадать с уровнем (в нижнем регистре, например, error). +* Один метод должен принимать в качестве аргумента строку, которая должна быть выведена на экран в качестве *MESSAGE*. +* Второй метод должен принимать первым параметром шаблон сообщения (в любом формате, например `java.lang.String.format()` или `java.text.MessageFormat.format()` +* и любым количеством дополнительных аргументов, которые будут использоваться для форматирования переданной строки. -* Добавить два метода с названием `log`, первый из которых принимает на вход два параметра - уровень логгирования и сообщение. Второй - уровень логгирования, шаблон сообщения и любое количество аргументов, которые будут подставлены в шаблон +* Добавить два метода с названием `log`, первый из которых принимает на вход два параметра - уровень логгирования и сообщение. +* Второй - уровень логгирования, шаблон сообщения и любое количество аргументов, которые будут подставлены в шаблон * `Logger` должен поддерживать динамическое задание текущего уровня важности. Сообщение, чей уровень важности ниже установленного не должны печататься в консоль. diff --git a/task01/src/com/example/task01/Logger.java b/task01/src/com/example/task01/Logger.java new file mode 100644 index 00000000..9778e76b --- /dev/null +++ b/task01/src/com/example/task01/Logger.java @@ -0,0 +1,103 @@ +package com.example.task01; + +import java.util.ArrayList; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class Logger { + private final String name; + private static final ArrayList loggers = new ArrayList<>(); + private Level level; + + public enum Level { + DEBUG, + INFO, + WARNING, + ERROR + } + + private static final DateTimeFormatter FORMATTER = + DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss"); + + private String getCurrentDateTime() { + return LocalDateTime.now().format(FORMATTER); + } + + + public String getName(){ + return name; + } + + public Level getLevel(){ + return level; + } + + public void setLevel(Level level){ + this.level = level; + } + + private Logger(String name, Level level){ + this.name = name; + this.level = level; + loggers.add(this); + } + + public static Logger getLogger(String name){ + for (Logger l : loggers){ + if (l.getName().equals(name)) return l; + } + return new Logger(name, Level.DEBUG); + } + + public void debug(String message){ + log(Level.DEBUG, message); + } + + public void debug(String pattern, Object... args){ + log(Level.DEBUG, pattern, args); + } + + public void info(String message){ + log(Level.INFO, message); + } + + public void info(String pattern, Object... args){ + log(Level.INFO, pattern, args); + } + + public void warning(String message){ + log(Level.WARNING, message); + } + + public void warning(String pattern, Object... args){ + log(Level.WARNING, pattern, args); + } + + public void error(String message){ + log(Level.ERROR, message); + } + + public void error(String pattern, Object... args){ + log(Level.ERROR, pattern, args); + } + + private void printLogMessage(Level level, String message) { + String datetime = getCurrentDateTime(); + String logMessage = String.format("[%s] %s %s - %s", + level, datetime, name, message); + System.out.println(logMessage); + } + + public void log(Level level, String message){ + if (level.ordinal() >= this.level.ordinal()){ + printLogMessage(level, message); + } + } + + public void log(Level level, String pattern, Object... args){ + if (level.ordinal() >= this.level.ordinal()){ + String formattedMessage = String.format(pattern, args); + printLogMessage(level, formattedMessage); + } + } +} \ No newline at end of file diff --git a/task01/src/com/example/task01/Task01Main.java b/task01/src/com/example/task01/Task01Main.java index 9973557d..090f4c40 100644 --- a/task01/src/com/example/task01/Task01Main.java +++ b/task01/src/com/example/task01/Task01Main.java @@ -2,6 +2,23 @@ public class Task01Main { public static void main(String[] args) { + Logger logger1 = Logger.getLogger("test"); + Logger logger2 = Logger.getLogger("test"); + System.out.println(logger1 == logger2); + + logger1.setLevel(Logger.Level.INFO); + + logger1.debug("Это сообщение не должно появиться"); // DEBUG < INFO + logger1.info("Информационное сообщение"); + logger1.warning("Предупреждение!"); + logger1.error("Ошибка!"); + + logger1.info("Пользователь %s вошел в систему", "Анна"); + logger1.warning("Осталось %d попыток", 3); + + Logger logger3 = Logger.getLogger("test2"); + logger3.setLevel(Logger.Level.DEBUG); + logger3.debug("3 логгер"); } -} +} \ No newline at end of file diff --git a/task02/src/com/example/task02/DiscountBill.java b/task02/src/com/example/task02/DiscountBill.java new file mode 100644 index 00000000..b38a61cc --- /dev/null +++ b/task02/src/com/example/task02/DiscountBill.java @@ -0,0 +1,18 @@ +package com.example.task02; + +public class DiscountBill extends Bill{ + private final int discount; + public DiscountBill(int discount) { + this.discount = discount; + } + public String getDiscount() { + return discount + "%"; + } + public long getAbsoluteDiscount(){ + return (long)(super.getPrice() * ((double)discount / 100)); + } + @Override + public long getPrice() { + return super.getPrice() - getAbsoluteDiscount(); + } +} \ No newline at end of file diff --git a/task02/src/com/example/task02/Task02Main.java b/task02/src/com/example/task02/Task02Main.java index e589f2d3..ec6fe2df 100644 --- a/task02/src/com/example/task02/Task02Main.java +++ b/task02/src/com/example/task02/Task02Main.java @@ -1,21 +1,24 @@ package com.example.task02; public class Task02Main { + public static void main(String[] args) { + // Создаем товары + Item milk = new Item("Молоко", 80); + Item bread = new Item("Хлеб", 40); + Item cheese = new Item("Сыр", 200); - private static final Item ITEM1 = new Item("Товар 1", 10); - private static final Item ITEM2 = new Item("Товар 2", 20); - private static final Item ITEM3 = new Item("Товар 3", 30); - private static final Item ITEM4 = new Item("Товар 4", 40); - private static final Item ITEM5 = new Item("Товар 5", 50); - private static final Item ITEM6 = new Item("Товар 6", 60); - public static void main(String[] args) { - Bill bill = new Bill(); - bill.add(ITEM1, 10); - bill.add(ITEM3, 3); - bill.add(ITEM6, 1); - System.out.println(bill); - bill.add(ITEM3, 3); - System.out.println(bill); + DiscountBill bill = new DiscountBill(20); // Создаем счет со скидкой 20% + + bill.add(milk, 2); // 2 * 80 = 160 + bill.add(bread, 1); // 1 * 40 = 40 + bill.add(cheese, 1); // 1 * 200 = 200 + // Итого без скидки: 400 + + System.out.println("Размер скидки: " + bill.getDiscount()); + System.out.println("Абсолютная скидка: " + bill.getAbsoluteDiscount() + " руб."); + System.out.println("Общая сумма со скидкой: " + bill.getPrice()); + + System.out.println("\n" + bill.toString()); } -} +} \ No newline at end of file diff --git a/task03/src/com/example/task03/Hours.java b/task03/src/com/example/task03/Hours.java new file mode 100644 index 00000000..0676e035 --- /dev/null +++ b/task03/src/com/example/task03/Hours.java @@ -0,0 +1,30 @@ +package com.example.task03; + +public class Hours implements TimeUnit { + + private final long amount; + + public Hours(long amount) { + this.amount = amount; + } + + @Override + public long toMillis() { + return amount * 60 * 60 * 1000; + } + + @Override + public long toSeconds() { + return amount * 60 * 60; + } + + @Override + public long toMinutes() { + return amount * 60; + } + + @Override + public long toHours() { + return amount; + } +} diff --git a/task03/src/com/example/task03/Milliseconds.java b/task03/src/com/example/task03/Milliseconds.java index 5115bc7d..8a784180 100644 --- a/task03/src/com/example/task03/Milliseconds.java +++ b/task03/src/com/example/task03/Milliseconds.java @@ -18,11 +18,13 @@ public long toMillis() { @Override public long toSeconds() { - return amount / 1000; + return Math.round(amount / 1000.0); } @Override public long toMinutes() { - return amount / 1000 * 60; + return Math.round(amount / (1000.0 * 60.0)); } + @Override + public long toHours() { return Math.round(amount / (1000.0 * 60.0 * 60.0)); } } diff --git a/task03/src/com/example/task03/Minutes.java b/task03/src/com/example/task03/Minutes.java index d6fa0594..f9732ae5 100644 --- a/task03/src/com/example/task03/Minutes.java +++ b/task03/src/com/example/task03/Minutes.java @@ -2,26 +2,29 @@ public class Minutes implements TimeUnit { + private final long amount; + public Minutes(long amount) { - // TODO: реализовать - throw new UnsupportedOperationException(); + this.amount = amount; } @Override public long toMillis() { - // TODO: реализовать - throw new UnsupportedOperationException(); + return amount * 60 * 1000; } @Override public long toSeconds() { - // TODO: реализовать - throw new UnsupportedOperationException(); + return amount * 60; } @Override public long toMinutes() { - // TODO: реализовать - throw new UnsupportedOperationException(); + return amount; + } + + @Override + public long toHours() { + return Math.round(amount / 60.0); } } diff --git a/task03/src/com/example/task03/Seconds.java b/task03/src/com/example/task03/Seconds.java index ce6bc213..741fc2c6 100644 --- a/task03/src/com/example/task03/Seconds.java +++ b/task03/src/com/example/task03/Seconds.java @@ -23,6 +23,9 @@ public long toSeconds() { @Override public long toMinutes() { - return Math.round(amount / 60); + return Math.round(amount / 60.0); } + + @Override + public long toHours() { return Math.round(amount / (60.0 * 60.0)); } } diff --git a/task03/src/com/example/task03/Task03Main.java b/task03/src/com/example/task03/Task03Main.java index ff0f14b0..2dba5a80 100644 --- a/task03/src/com/example/task03/Task03Main.java +++ b/task03/src/com/example/task03/Task03Main.java @@ -4,11 +4,15 @@ public class Task03Main { public static void main(String[] args) { TimeUnit unit1 = new Seconds(1000); printTimeUnit(unit1); + + TimeUnit hours = new Hours(5); + printTimeUnit(hours); } private static void printTimeUnit(TimeUnit unit) { System.out.println(String.format("Milliseconds: %d", unit.toMillis())); System.out.println(String.format("Seconds: %d", unit.toSeconds())); System.out.println(String.format("Minutes: %d", unit.toMinutes())); + System.out.println(String.format("Hours: %d", unit.toHours())); } } diff --git a/task03/src/com/example/task03/TimeUnit.java b/task03/src/com/example/task03/TimeUnit.java index 3b123fb8..a9ee6ead 100644 --- a/task03/src/com/example/task03/TimeUnit.java +++ b/task03/src/com/example/task03/TimeUnit.java @@ -27,5 +27,7 @@ public interface TimeUnit { * @return количество минут в текущем интервале */ long toMinutes(); + /** Возвращает количество часов в текущем интервале */ + long toHours(); } diff --git a/task03/src/com/example/task03/TimeUnitUtils.java b/task03/src/com/example/task03/TimeUnitUtils.java index 790f8850..08fbe6ee 100644 --- a/task03/src/com/example/task03/TimeUnitUtils.java +++ b/task03/src/com/example/task03/TimeUnitUtils.java @@ -24,4 +24,8 @@ public static Milliseconds toMillis(Seconds seconds) { public static Seconds toSeconds(Milliseconds millis) { return new Seconds(millis.toSeconds()); } + + public static Minutes toMinutes(Seconds seconds) { return new Minutes(seconds.toMinutes()); } + + public static Hours toHours(Minutes minutes) { return new Hours(minutes.toHours()); } } diff --git a/task04/README.md b/task04/README.md index 2ab3302c..f24c804b 100644 --- a/task04/README.md +++ b/task04/README.md @@ -8,7 +8,8 @@ В качестве конечных обработчиков сообщений нужно реализовать следующие: * `ConsoleHandler` - обработчик, выводящий сообщения в консоль * `FileHandler` - обработчик, выводящий сообщения в файл -* `RotationFileHandler` - обработчик, выводящий сообщения в файл с определенной ротацией - например, для каждого часа создается свой файл. Для данного обработчика нужно иметь возможность выставлять интервал ротации (например, с помощью java.time.temporal.ChronoUnit, либо другим удобным способом). +* `RotationFileHandler` - обработчик, выводящий сообщения в файл с определенной ротацией - например, для каждого часа создается свой файл. +* Для данного обработчика нужно иметь возможность выставлять интервал ротации (например, с помощью java.time.temporal.ChronoUnit, либо другим удобным способом). * `MemoryHandler` - обработчик - прокси, который может аккумулировать сообщения в памяти и при необходимости (явном вызове метода или при достижении определенного объема) отправлять их в проксируемый обработчик. Например, с помощью данного класса мы должны уметь отправлять сообщения в консоль (или файл), но только определенными "порциями". diff --git a/task04/src/com/example/task04/ConsoleHandler.java b/task04/src/com/example/task04/ConsoleHandler.java new file mode 100644 index 00000000..49f4d2e9 --- /dev/null +++ b/task04/src/com/example/task04/ConsoleHandler.java @@ -0,0 +1,8 @@ +package com.example.task04; + +public class ConsoleHandler implements MessageHandler { + @Override + public void handle(String message) { + System.out.println(message); + } +} diff --git a/task04/src/com/example/task04/FileHandler.java b/task04/src/com/example/task04/FileHandler.java new file mode 100644 index 00000000..e7e78376 --- /dev/null +++ b/task04/src/com/example/task04/FileHandler.java @@ -0,0 +1,23 @@ +package com.example.task04; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; + +public class FileHandler implements MessageHandler { + private String fileName; + + public FileHandler(String fileName) { + this.fileName = fileName; + } + + @Override + public void handle(String message) { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true))) { + writer.write(message); + writer.newLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/task04/src/com/example/task04/Level.java b/task04/src/com/example/task04/Level.java new file mode 100644 index 00000000..277816f3 --- /dev/null +++ b/task04/src/com/example/task04/Level.java @@ -0,0 +1,8 @@ +package com.example.task04; + +public enum Level { + DEBUG, + INFO, + WARNING, + ERROR +} diff --git a/task04/src/com/example/task04/Logger.java b/task04/src/com/example/task04/Logger.java new file mode 100644 index 00000000..da98ec60 --- /dev/null +++ b/task04/src/com/example/task04/Logger.java @@ -0,0 +1,41 @@ +package com.example.task04; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +public class Logger { + private String name; + private Level level; + private List handlers = new ArrayList<>(); + + public Logger(String name, Level level) { + this.name = name; + this.level = level; + } + + public void addHandler(MessageHandler handler) { + handlers.add(handler); + } + + private String formatMessage(Level level, String message) { + String date = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()); + return String.format("[%s] %s %s - %s", level.name(), date, name, message); + } + + public void log(Level level, String message) { + if (level.ordinal() >= this.level.ordinal()) { + String formatted = formatMessage(level, message); + for (MessageHandler h : handlers) { + h.handle(formatted); + } + } + } + + // Удобные методы для каждого уровня + public void debug(String message) { log(Level.DEBUG, message); } + public void info(String message) { log(Level.INFO, message); } + public void warning(String message) { log(Level.WARNING, message); } + public void error(String message) { log(Level.ERROR, message); } +} diff --git a/task04/src/com/example/task04/MemoryHandler.java b/task04/src/com/example/task04/MemoryHandler.java new file mode 100644 index 00000000..60dd6072 --- /dev/null +++ b/task04/src/com/example/task04/MemoryHandler.java @@ -0,0 +1,21 @@ +package com.example.task04; + +import java.util.ArrayList; + +public class MemoryHandler implements MessageHandler { + private ArrayList memory = new ArrayList<>(); + private int limit = 10; + private ConsoleHandler handler = new ConsoleHandler(); + + @Override + public void handle(String message) { + if (memory.size() < limit) { + memory.add(message); + } else { + for (String element : memory) { + handler.handle(element); + } + memory.clear(); + } + } +} \ No newline at end of file diff --git a/task04/src/com/example/task04/MessageHandler.java b/task04/src/com/example/task04/MessageHandler.java new file mode 100644 index 00000000..d0649a7c --- /dev/null +++ b/task04/src/com/example/task04/MessageHandler.java @@ -0,0 +1,5 @@ +package com.example.task04; + +public interface MessageHandler { + void handle(String message); +} \ No newline at end of file diff --git a/task04/src/com/example/task04/RotationFileHandler.java b/task04/src/com/example/task04/RotationFileHandler.java new file mode 100644 index 00000000..d013c409 --- /dev/null +++ b/task04/src/com/example/task04/RotationFileHandler.java @@ -0,0 +1,20 @@ +package com.example.task04; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class RotationFileHandler implements MessageHandler { + private MessageHandler currentFileHandler; + private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH"); + private String lastFileName = ""; + + @Override + public void handle(String message) { + String currentFile = "log_" + LocalDateTime.now().format(formatter) + ".txt"; + if (!currentFile.equals(lastFileName)) { + lastFileName = currentFile; + currentFileHandler = new FileHandler(currentFile); + } + currentFileHandler.handle(message); + } +} diff --git a/task04/src/com/example/task04/Task04Main.java b/task04/src/com/example/task04/Task04Main.java index 55917a30..3bf26133 100644 --- a/task04/src/com/example/task04/Task04Main.java +++ b/task04/src/com/example/task04/Task04Main.java @@ -2,6 +2,16 @@ public class Task04Main { public static void main(String[] args) { + Logger logger = new Logger("MyLogger", Level.DEBUG); + logger.addHandler(new ConsoleHandler()); + logger.addHandler(new FileHandler("all_logs.txt")); + logger.addHandler(new RotationFileHandler()); + logger.addHandler(new MemoryHandler()); + + logger.debug("Debug message"); + logger.info("Info message"); + logger.warning("Warning message"); + logger.error("Error message"); } }