Что такое шаблон проектирования и зачем он нам нужен?
Шаблон проектирования обеспечивает качественно выполненное решение для конкретной проблемы/задачи. Он не содержит какой-либо реализации по умолчанию, поэтому шаблон позволяет нам эффективно разрабатывать нашу программу, чтобы ее было легко поддерживать, и чтобы она было удобочитаема и ее можно было использоваться повторно.
Типы шаблонов проектирования?
Creational Design Pattern → Он помогает нам создавать объекты эффективным способом.
Structural Design Pattern - Шаблон структурного проектирования
Behavioral Design Pattern -Шаблон поведенческого проектирования
1. 1.Singleton Design Pattern Одноэлементный шаблон проектирования
Этот шаблон помогает в создании одного экземпляра класса и повторном использовании других классов без создания нового.
Его классифицируют на два типа
Early Instantiation Раннее создание экземпляра → создание экземпляра во время выполнения кода
Lazy Instantiation - ленивое создание экземпляра → создание экземпляра по необходимости
Static factory method - статический фабричный метод → это глобальная точка, где мы можем получить доступ к объекту из другого класса и вернуть экземпляр для вызывающей стороны.
Давайте посмотрим на пример одноэлементного класса в JAVA:
class HelloWorld {
public static void main(String[] args) {
A obj = A.getInstance();
obj.doSomething();
}
}
class A {
private static A a = new A();//Early Instantiation instance created at load time
private A() {
}
public static A getInstance() {
return a;
}
public void doSomething() {
System.out.println("Hello, World!");
}
}
Давайте посмотрим на пример singleton class в JAVA с отложенным Lazy Instantiation.
class A {
private static A a;
private A() {
}
public static A getInstance() {
if(a == null) {
synchronized(Singleton.class) {
if(a == null) {
a = Singleton();//Lazy Instantiation creating instance when required
}
}
}
return a;
}
public void doSomething() {
System.out.println("Hello, World!");
}
}
Давайте посмотрим на пример одноэлементного класса в Kotlin.
В kotlin мы создаем singleton класс, используя ключевое слово объекта.
fun main() {
A.doSomething()
A.result = "Hi World"
A.doSomething()
}
object A {
var result = "Hello World!!";
init {
println("Class Invoked")
}
fun doSomething(){
println(result)
}
}
2. Фабричный метод
Второй паттерн, который мы увидим в списке паттернов проектирования, — это фабричный паттерн проектирования. Шаблон фабричного проектирования определяет абстрактный класс или интерфейс для создания объекта и позволяет подклассу нести ответственность за создание экземпляра класса. Давайте посмотрим на примере:
abstract class Pack {
int amount;
abstract void getPackAmount();
public int calaculateamount(int days)
{
return days*amount;
}
}
class Limited extends Pack{
void getPackAmount()
{
amount = 10;
}
}
class UNLimited extends Pack{
void getPackAmount()
{
amount = 30;
}
}
class FactoryMain {
Pack getPlantype(String plantype) {
if(plantype.equals("limited"))
return new Limited();
else
return new UNLimited();
}
}
Давайте посмотрим на пример в Kotlin
fun main() {
val fa = FactoryMain()
val obj = fa.getPlantype("limited")
obj.getAmount()
println(obj.calaculate(10))
}
abstract class Plan {
var amount:Int = 0;
abstract fun getAmount();
fun calaculate(days:Int):Int {
return amount*days;
}
}
class limited : Plan() {
override fun getAmount() {
amount = 70
}
}
class unlimited : Plan() {
override fun getAmount() {
amount = 200
}
}
class FactoryMain {
fun getPlantype(type:String):Plan
{
if(type.equals("limited"))
return limited()
else
return unlimited()
}
}
3. Шаблон прототипа
Вместо создания нового объекта мы будем клонировать существующий объект и вносить изменения в клонированный объект.
Давайте посмотрим на пример в JAVA
public class Employee implements Cloneable {
ArrayList<String> emplist;
Employee() {
emplist = new ArrayList<String>();
}
Employee(ArrayList<String> emp)
{
this.emplist = emp;
}
void loadData() {
emplist.add("Pandiyan");
emplist.add("Sai Kumaran");
}
ArrayList<String> getData() {
return emplist;
}
@Override
public Object clone(){
ArrayList<String> newemlist = new ArrayList<String>();
for(String name : emplist) {
newemlist.add(name);
}
return new Employee(newemlist);
}
}
Далее идет наш основной класс в JAVA
Employee em = new Employee();
em.loadData();
Employee em1 = (Employee)em.clone();
Employee em2 = (Employee)em.clone();
ArrayList<String> list1 = em1.getData();
list1.remove("Pandiyan");
ArrayList<String> list2 = em2.getData();
list2.add("Sara Sri");
в приведенном выше примере я создаю два клонированных объекта из существующего объекта em.
Давайте посмотрим на пример в Котлине
class Employees : Cloneable {
var list = mutableListOf<String>()
fun updatelist(newlist:MutableList<String>) {
this.list = newlist
}
fun loaddata(){
list.add("Pandiyan")
list.add("Sai Kumaran")
}
fun getData():MutableList<String> {
return list
}
public override fun clone() {
var newlist = mutableListOf<String>()
for(i in 0..(list.size-1)) {
newlist.add(list[i])
}
return updatelist(newlist)
}
}
За ним следует основной класс kotlin
val em = Employees()
em.loaddata()
val em1 = em.clone() as Employees
val em2 = em.clone() as Employees
val list1 = em1.getData()
list1.add("Sara Sri")
val list2 = em2.getData()
list2.remove("Pandiyan")