Procházet zdrojové kódy

add decorator pattern

MrOzOn před 4 roky
rodič
revize
8c0448d4a3

+ 28 - 1
src/structural_patterns/README.MD

@@ -82,4 +82,31 @@
 
 **_Важно_**
 
-Иногда бывает нужно, чтобы составной объект мог включать только определенные виды компонентов. Паттерн компоновщик не позволяет воспользоваться для реализации таких ограничений статической системой типов. Вместо этого приходится проводить проверки во время выполнения.
+Иногда бывает нужно, чтобы составной объект мог включать только определенные виды компонентов. Паттерн компоновщик не позволяет воспользоваться для реализации таких ограничений статической системой типов. Вместо этого приходится проводить проверки во время выполнения.
+
+# [Декоратор (Decorator)](./decorator/main.kt)
+
+Это структурный паттерн проектирования, который позволяет динамически добавлять объектам новую функциональность, оборачивая их в полезные «обёртки».
+Является гибкой альтернативой порождению подклассов с целью расширения функциональности.
+
+## Применимость
+
+- динамическое, прозрачное для клиентов добавление обязанностей объектам (не затрагивающее другие объекты)
+- реализация обязанностей, которые могут быть сняты с объекта
+- расширение путем порождения подклассов по каким-то причинам неудобно или невозможно. Иногда приходится реализовывать много независимых расширений, так что порождение подклассов для поддержки всех возможных комбинаций приведет к стремительному росту их числа. В других случаях определение класса может быть скрыто или почему-либо еще недоступно, так что породить от него подкласс нельзя.
+
+## Отношения
+
+Decorator переадресует запросы объекту Component. Может выполнять и дополнительные операции до и после переадресации.
+
+## Результаты
+
+У паттерна декоратор есть, по крайней мере, два плюса и два минуса
+
+_+_
+- большая гибкость, нежели у статического наследования
+- позволяет избежать перегруженных функциями классов на верхних уровнях иерархии
+
+_-_
+- декоратор и его компонент не идентичны. Декоратор действует как прозрачное обрамление. Но декорированный компонент все же не идентичен исходному.
+- множество мелких объектов. При использовании в проекте этого паттерна нередко формируется система, составленная из большого числа мелких объектов, похожих друг на друга. Такие объекты различаются только способом взаимосвязи, а не классом и не значениями своих внутренних переменных. Хотя такие системы легко настраиваются проектировщиком, хорошо разбирающимся в их строении, изучать и отлаживать их очень тяжело.

+ 38 - 0
src/structural_patterns/decorator/DataSourceDecorators.kt

@@ -0,0 +1,38 @@
+package structural_patterns.decorator
+
+open class DataSourceDecorator(private val source: DataSource): DataSource {
+    override fun writeData(data: String) {
+        source.writeData(data)
+    }
+
+    override fun readData(): String {
+        return source.readData()
+    }
+
+}
+
+class EncryptionDecorator(private val source: DataSource): DataSourceDecorator(source) {
+    override fun writeData(data: String) {
+        println("encrypt \"$data\" before write")
+        super.writeData(data)
+    }
+
+    override fun readData(): String {
+        val data = super.readData()
+        println("decrypt data before return")
+        return data
+    }
+}
+
+class CompressionDecorator(private val source: DataSource): DataSourceDecorator(source) {
+    override fun writeData(data: String) {
+        println("compress \"$data\" before write")
+        super.writeData(data)
+    }
+
+    override fun readData(): String {
+        val data = super.readData()
+        println("decompress data before return")
+        return data
+    }
+}

+ 16 - 0
src/structural_patterns/decorator/DataSources.kt

@@ -0,0 +1,16 @@
+package structural_patterns.decorator
+
+interface DataSource {
+    fun writeData(data: String)
+    fun readData(): String
+}
+
+class FileDataSource(private val fileName: String): DataSource {
+    override fun writeData(data: String) {
+        println("write \"$data\" in file $fileName")
+    }
+    override fun readData(): String {
+        println("read data from file $fileName")
+        return "bla-bla"
+    }
+}

+ 17 - 0
src/structural_patterns/decorator/main.kt

@@ -0,0 +1,17 @@
+package structural_patterns.decorator
+
+fun main(){
+    println("\tpure data")
+    var source: DataSource  = FileDataSource("sensitive.dat")
+    source.writeData("secret")
+    println("\n\tpure + compress data")
+    source = CompressionDecorator(source)
+    source.writeData("secret")
+    println("\n\tpure + compress + encrypt data")
+    source = EncryptionDecorator(source)
+    source.writeData("secret")
+    // OR
+    println("\nall together")
+    val source1: DataSource  = CompressionDecorator(EncryptionDecorator(FileDataSource("sensitive.dat")))
+    source1.writeData("secret")
+}