JavaRush /Java Blog /Random-TL /Mga Pattern ng Disenyo sa Java

Mga Pattern ng Disenyo sa Java

Nai-publish sa grupo
Ang mga pattern o mga pattern ng disenyo ay isang madalas na hindi napapansing bahagi ng trabaho ng isang developer, na nagpapahirap sa code na panatilihin at iakma sa mga bagong kinakailangan. Iminumungkahi kong tingnan mo kung ano ito at kung paano ito ginagamit sa JDK. Naturally, ang lahat ng mga pangunahing pattern sa isang anyo o iba pa ay nasa paligid natin sa loob ng mahabang panahon. Tingnan natin ang mga ito sa pagsusuring ito.
Mga Pattern ng Disenyo sa Java - 1
Nilalaman:

Mga template

Ang isa sa mga pinakakaraniwang kinakailangan sa mga bakante ay "Kaalaman sa mga pattern." Una sa lahat, sulit na sagutin ang isang simpleng tanong - "Ano ang Pattern ng Disenyo?" Ang pattern ay isinalin mula sa Ingles bilang "template". Ibig sabihin, ito ay isang tiyak na pattern ayon sa kung saan may ginagawa tayo. Ang parehong ay totoo sa programming. Mayroong ilang mga itinatag na pinakamahusay na kasanayan at diskarte sa paglutas ng mga karaniwang problema. Ang bawat programmer ay isang arkitekto. Kahit na lumikha ka lamang ng ilang mga klase o kahit isa, ito ay depende sa iyo kung gaano katagal ang code ay maaaring mabuhay sa ilalim ng pagbabago ng mga kinakailangan, kung gaano ito maginhawang gamitin ng iba. At dito makakatulong ang kaalaman sa mga template, dahil... Papayagan ka nitong mabilis na maunawaan kung paano pinakamahusay na magsulat ng code nang hindi muling sinusulat ito. Tulad ng alam mo, ang mga programmer ay mga tamad na tao at mas madaling magsulat kaagad ng isang bagay kaysa sa muling gawin ito nang maraming beses) Ang mga pattern ay maaaring mukhang katulad din ng mga algorithm. Pero may pagkakaiba sila. Binubuo ang algorithm ng mga partikular na hakbang na naglalarawan ng mga kinakailangang aksyon. Inilalarawan lamang ng mga pattern ang diskarte, ngunit hindi inilalarawan ang mga hakbang sa pagpapatupad. Ang mga pattern ay naiiba, dahil ... lutasin ang iba't ibang problema. Karaniwan ang mga sumusunod na kategorya ay nakikilala:
  • Generative

    Nilulutas ng mga pattern na ito ang problema sa paggawa ng bagay na flexible

  • Structural

    Nilulutas ng mga pattern na ito ang problema ng epektibong pagbuo ng mga koneksyon sa pagitan ng mga bagay

  • Pag-uugali

    Ang mga pattern na ito ay malulutas ang problema ng epektibong pakikipag-ugnayan sa pagitan ng mga bagay

Upang isaalang-alang ang mga halimbawa, iminumungkahi ko ang paggamit ng online code compiler repl.it.
Mga Pattern ng Disenyo sa Java - 2

Mga pattern ng paglikha

Magsimula tayo sa simula ng ikot ng buhay ng mga bagay - sa paglikha ng mga bagay. Nakakatulong ang mga generative na template na lumikha ng mga bagay nang mas maginhawa at nagbibigay ng flexibility sa prosesong ito. Ang isa sa pinakatanyag ay ang " Tagabuo ". Ang pattern na ito ay nagbibigay-daan sa iyo upang lumikha ng mga kumplikadong bagay nang sunud-sunod. Sa Java, ang pinakatanyag na halimbawa ay StringBuilder:
class Main {
  public static void main(String[] args) {
    StringBuilder builder = new StringBuilder();
    builder.append("Hello");
    builder.append(',');
    builder.append("World!");
    System.out.println(builder.toString());
  }
}
Ang isa pang kilalang diskarte sa paglikha ng isang bagay ay ang paglipat ng paglikha sa isang hiwalay na paraan. Ang pamamaraang ito ay nagiging, kumbaga, isang pabrika ng bagay. Kaya naman ang pattern ay tinatawag na " Factory Method ". Sa Java, halimbawa, ang epekto nito ay makikita sa klase java.util.Calendar. Ang klase mismo Calendaray abstract, at para likhain ito ginagamit ang pamamaraan getInstance:
import java.util.*;
class Main {
  public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();
    System.out.println(calendar.getTime());
    System.out.println(calendar.getClass().getCanonicalName());
  }
}
Kadalasan ito ay dahil ang lohika sa likod ng paglikha ng bagay ay maaaring kumplikado. Halimbawa, sa kaso sa itaas, ina-access namin ang base class Calendar, at nilikha ang klase GregorianCalendar. Kung titingnan natin ang constructor, makikita natin na ang iba't ibang mga pagpapatupad ay nilikha depende sa mga kondisyon Calendar. Ngunit kung minsan ang isang paraan ng pabrika ay hindi sapat. Minsan kailangan mong lumikha ng iba't ibang mga bagay upang magkasya ang mga ito. Ang isa pang template ay makakatulong sa amin dito - " Abstract factory ". At pagkatapos ay kailangan nating lumikha ng iba't ibang mga pabrika sa isang lugar. Kasabay nito, ang kalamangan ay ang mga detalye ng pagpapatupad ay hindi mahalaga sa amin, i.e. hindi mahalaga kung aling partikular na pabrika ang nakukuha namin. Ang pangunahing bagay ay na ito ay lumilikha ng tamang pagpapatupad. Super halimbawa:
Mga Pattern ng Disenyo sa Java - 3
Iyon ay, depende sa kapaligiran (operating system), makakakuha tayo ng isang tiyak na pabrika na lilikha ng mga katugmang elemento. Bilang alternatibo sa paraan ng paglikha sa pamamagitan ng ibang tao, maaari naming gamitin ang pattern na " Prototype ". Ang kakanyahan nito ay simple - ang mga bagong bagay ay nilikha sa imahe at pagkakahawig ng mayroon nang mga bagay, i.e. ayon sa kanilang prototype. Sa Java, lahat ay nakatagpo ng pattern na ito - ito ang paggamit ng isang interface java.lang.Cloneable:
class Main {
  public static void main(String[] args) {
    class CloneObject implements Cloneable {
      @Override
      protected Object clone() throws CloneNotSupportedException {
        return new CloneObject();
      }
    }
    CloneObject obj = new CloneObject();
    try {
      CloneObject pattern = (CloneObject) obj.clone();
    } catch (CloneNotSupportedException e) {
      //Do something
    }
  }
}
Gaya ng nakikita mo, hindi alam ng tumatawag kung paano ang clone. Iyon ay, ang paglikha ng isang bagay batay sa isang prototype ay ang responsibilidad ng bagay mismo. Ito ay kapaki-pakinabang dahil hindi nito itinatali ang user sa pagpapatupad ng template object. Well, ang pinakahuli sa listahang ito ay ang pattern na "Singleton". Ang layunin nito ay simple - upang magbigay ng isang solong halimbawa ng isang bagay para sa buong aplikasyon. Ang pattern na ito ay kawili-wili dahil madalas itong nagpapakita ng mga problema sa multithreading. Para sa mas malalim na pagtingin, tingnan ang mga artikulong ito:
Mga Pattern ng Disenyo sa Java - 4

Mga pattern ng istruktura

Sa paglikha ng mga bagay ay naging mas malinaw. Ngayon ang oras upang tingnan ang mga pattern ng istruktura. Ang kanilang layunin ay bumuo ng mga hierarchy ng klase na madaling suportahan at ang kanilang mga relasyon. Ang isa sa mga una at kilalang pattern ay " Deputy " (Proxy). Ang proxy ay may parehong interface bilang ang tunay na bagay, kaya walang pagkakaiba para sa kliyente na gumana sa pamamagitan ng proxy o direkta. Ang pinakasimpleng halimbawa ay java.lang.reflect.Proxy :
import java.util.*;
import java.lang.reflect.*;
class Main {
  public static void main(String[] arguments) {
    final Map<String, String> original = new HashMap<>();
    InvocationHandler proxy = (obj, method, args) -> {
      System.out.println("Invoked: " + method.getName());
      return method.invoke(original, args);
    };
    Map<String, String> proxyInstance = (Map) Proxy.newProxyInstance(
        original.getClass().getClassLoader(),
        original.getClass().getInterfaces(),
        proxy);
    proxyInstance.put("key", "value");
    System.out.println(proxyInstance.get("key"));
  }
}
Tulad ng nakikita mo, sa halimbawa mayroon kaming orihinal - ito ang HashMapnagpapatupad ng interface Map. Susunod kaming lumikha ng isang proxy na pumapalit sa orihinal HashMappara sa bahagi ng kliyente, na tinatawag na putat mga pamamaraan get, pagdaragdag ng aming sariling lohika sa panahon ng tawag. Tulad ng nakikita natin, ang pakikipag-ugnayan sa pattern ay nangyayari sa pamamagitan ng mga interface. Ngunit kung minsan ang isang kapalit ay hindi sapat. At pagkatapos ay maaaring gamitin ang pattern na " Dekorador ". Ang dekorador ay tinatawag ding wrapper o wrapper. Ang proxy at dekorador ay halos magkapareho, ngunit kung titingnan mo ang halimbawa, makikita mo ang pagkakaiba:
import java.util.*;
class Main {
  public static void main(String[] arguments) {
    List<String> list = new ArrayList<>();
    List<String> decorated = Collections.checkedList(list, String.class);
    decorated.add("2");
    list.add("3");
    System.out.println(decorated);
  }
}
Hindi tulad ng isang proxy, binabalot ng isang dekorador ang sarili nito sa isang bagay na ipinasa bilang input. Maaaring tanggapin ng isang proxy kung ano ang kailangang i-proxie at pamahalaan ang buhay ng mismong na-proxy na bagay (halimbawa, lumikha ng isang na-proxy na bagay). May isa pang kawili-wiling pattern - " Adapter ". Ito ay katulad ng isang dekorador - ang dekorador ay kumukuha ng isang bagay bilang input at nagbabalik ng isang pambalot sa ibabaw ng bagay na ito. Ang pagkakaiba ay ang layunin ay hindi upang baguhin ang pag-andar, ngunit upang iakma ang isang interface sa isa pa. Ang Java ay may napakalinaw na halimbawa nito:
import java.util.*;
class Main {
  public static void main(String[] arguments) {
    String[] array = {"One", "Two", "Three"};
    List<String> strings = Arrays.asList(array);
    strings.set(0, "1");
    System.out.println(Arrays.toString(array));
  }
}
Sa input mayroon kaming isang array. Susunod, gumawa kami ng adaptor na nagdadala ng array sa interface List. Kapag nagtatrabaho dito, talagang nagtatrabaho kami sa isang array. Samakatuwid, ang pagdaragdag ng mga elemento ay hindi gagana, dahil... Hindi mababago ang orihinal na array. At sa kasong ito ay makakakuha tayo ng UnsupportedOperationException. Ang susunod na kawili-wiling diskarte sa pagbuo ng istraktura ng klase ay ang Composite pattern . Ito ay kagiliw-giliw na ang isang tiyak na hanay ng mga elemento gamit ang isang interface ay nakaayos sa isang tiyak na hierarchy na parang puno. Sa pamamagitan ng pagtawag sa isang paraan sa isang elemento ng magulang, nakakakuha kami ng tawag sa paraang ito sa lahat ng kinakailangang elemento ng bata. Ang pangunahing halimbawa ng pattern na ito ay ang UI (maging ito ay java.awt o JSF):
import java.awt.*;
class Main {
  public static void main(String[] arguments) {
    Container container = new Container();
    Component component = new java.awt.Component(){};
    System.out.println(component.getComponentOrientation().isLeftToRight());
    container.add(component);
    container.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
    System.out.println(component.getComponentOrientation().isLeftToRight());
  }
}
Tulad ng nakikita natin, nagdagdag kami ng isang bahagi sa lalagyan. At pagkatapos ay hiniling namin sa lalagyan na ilapat ang bagong oryentasyon ng mga bahagi. At ang lalagyan, na nalalaman kung anong mga bahagi ang binubuo nito, ay nagtalaga ng pagpapatupad ng utos na ito sa lahat ng mga sangkap ng bata. Ang isa pang kawili-wiling pattern ay ang pattern ng " Bridge ". Tinatawag itong ito dahil naglalarawan ito ng koneksyon o tulay sa pagitan ng dalawang magkaibang hierarchy ng klase. Ang isa sa mga hierarchy na ito ay itinuturing na isang abstraction at ang isa ay isang pagpapatupad. Ito ay naka-highlight dahil ang abstraction mismo ay hindi nagsasagawa ng mga aksyon, ngunit inilalaan ang pagpapatupad na ito sa pagpapatupad. Ang pattern na ito ay kadalasang ginagamit kapag may mga "control" na klase at ilang uri ng "platform" classes (halimbawa, Windows, Linux, atbp.). Sa diskarteng ito, ang isa sa mga hierarchy na ito (abstraction) ay makakatanggap ng reference sa mga object ng isa pang hierarchy (implementation) at ide-delegate ang pangunahing gawain sa kanila. Dahil ang lahat ng mga pagpapatupad ay susunod sa isang karaniwang interface, maaari silang palitan sa loob ng abstraction. Sa Java, ang isang malinaw na halimbawa nito ay java.awt:
Mga Pattern ng Disenyo sa Java - 5
Para sa karagdagang impormasyon, tingnan ang artikulong " Mga Pattern sa Java AWT ". Kabilang sa mga pattern ng istruktura, nais ko ring tandaan ang pattern na " Facade ". Ang kakanyahan nito ay upang itago ang pagiging kumplikado ng paggamit ng mga library/framework sa likod ng API na ito sa likod ng isang maginhawa at maigsi na interface. Halimbawa, maaari mong gamitin ang JSF o EntityManager mula sa JPA bilang isang halimbawa. Mayroon ding isa pang pattern na tinatawag na " Flyweight ". Ang kakanyahan nito ay kung ang iba't ibang mga bagay ay may parehong estado, kung gayon maaari itong maging pangkalahatan at maiimbak hindi sa bawat bagay, ngunit sa isang lugar. At pagkatapos ang bawat bagay ay makakapag-refer ng isang karaniwang bahagi, na magbabawas ng mga gastos sa memorya para sa imbakan. Ang pattern na ito ay kadalasang nagsasangkot ng pre-caching o pagpapanatili ng isang pool ng mga bagay. Kapansin-pansin, alam din natin ang pattern na ito mula pa sa simula:
Mga Pattern ng Disenyo sa Java - 6
Sa pamamagitan ng parehong pagkakatulad, isang pool ng mga string ay maaaring isama dito. Maaari mong basahin ang artikulo sa paksang ito: " Flyweight Design Pattern ".
Mga Pattern ng Disenyo sa Java - 7

Mga pattern ng pag-uugali

Kaya, nalaman namin kung paano malilikha ang mga bagay at kung paano maaayos ang mga koneksyon sa pagitan ng mga klase. Ang pinaka-kagiliw-giliw na bagay na natitira ay upang magbigay ng flexibility sa pagbabago ng pag-uugali ng mga bagay. At ang mga pattern ng pag-uugali ay makakatulong sa atin dito. Ang isa sa mga madalas na binabanggit na pattern ay ang pattern na " Strategy ". Dito nagsisimula ang pag-aaral ng mga pattern sa aklat na " Head First. Design Patterns ". Gamit ang pattern na "Diskarte", maaari tayong mag-imbak sa loob ng isang bagay kung paano natin isasagawa ang aksyon, i.e. ang bagay sa loob ay nag-iimbak ng isang diskarte na maaaring baguhin sa panahon ng pagpapatupad ng code. Ito ay isang pattern na madalas naming ginagamit kapag gumagamit ng isang comparator:
import java.util.*;
class Main {
  public static void main(String[] args) {
    List<String> data = Arrays.asList("Moscow", "Paris", "NYC");
    Comparator<String> comparator = Comparator.comparingInt(String::length);
    Set dataSet = new TreeSet(comparator);
    dataSet.addAll(data);
    System.out.println("Dataset : " + dataSet);
  }
}
Bago tayo - TreeSet. Mayroon itong pag-uugali ng TreeSetpagpapanatili ng pagkakasunud-sunod ng mga elemento, i.e. inaayos ang mga ito (dahil isa itong SortedSet). Ang pag-uugali na ito ay may default na diskarte, na nakikita natin sa JavaDoc: pag-uuri sa "natural na pagkakasunud-sunod" (para sa mga string, ito ay lexicographical order). Nangyayari ito kung gumagamit ka ng isang parameterless constructor. Ngunit kung gusto nating baguhin ang diskarte, maaari nating ipasa Comparator. Sa halimbawang ito, maaari naming gawin ang aming set bilang new TreeSet(comparator), at pagkatapos ay magbabago ang pagkakasunud-sunod ng pag-iimbak ng mga elemento (diskarte sa pag-iimbak) sa tinukoy sa comparator. Kapansin-pansin, mayroong halos parehong pattern na tinatawag na " Estado ". Sinasabi ng pattern na "Estado" na kung mayroon tayong ilang pag-uugali sa pangunahing bagay na nakasalalay sa estado ng bagay na ito, maaari nating ilarawan ang estado mismo bilang isang bagay at baguhin ang bagay ng estado. At italaga ang mga tawag mula sa pangunahing bagay sa estado. Ang isa pang pattern na kilala sa amin mula sa pag-aaral ng mga pangunahing kaalaman ng wikang Java ay ang pattern na " Command ". Ang pattern ng disenyo na ito ay nagmumungkahi na ang iba't ibang mga command ay maaaring katawanin bilang iba't ibang mga klase. Ang pattern na ito ay halos kapareho sa pattern ng Strategy. Ngunit sa pattern ng Strategy, muling tinutukoy namin kung paano isasagawa ang isang partikular na aksyon (halimbawa, pag-uuri sa TreeSet). Sa pattern na "Command," muling tinutukoy namin kung anong aksyon ang isasagawa. Ang pattern command ay kasama namin araw-araw kapag gumagamit kami ng mga thread:
import java.util.*;
class Main {
  public static void main(String[] args) {
    Runnable command = () -> {
      System.out.println("Command action");
    };
    Thread th = new Thread(command);
    th.start();
  }
}
Tulad ng nakikita mo, ang command ay tumutukoy sa isang aksyon o command na isasagawa sa isang bagong thread. Ito rin ay nagkakahalaga ng pagsasaalang-alang sa pattern na " Chain of responsibility ". Ang pattern na ito ay napaka-simple din. Sinasabi ng pattern na ito na kung may kailangang iproseso, maaari kang mangolekta ng mga humahawak sa isang chain. Halimbawa, ang pattern na ito ay kadalasang ginagamit sa mga web server. Sa input, may ilang kahilingan ang server mula sa user. Ang kahilingang ito ay dumaan sa chain ng pagpoproseso. Kasama sa hanay ng mga tagapangasiwa na ito ang mga filter (halimbawa, hindi tumatanggap ng mga kahilingan mula sa isang blacklist ng mga IP address), mga tagapangasiwa ng pagpapatotoo (pahintulutan lamang ang mga awtorisadong user), isang tagapangasiwa ng header ng kahilingan, isang tagapangasiwa ng caching, atbp. Ngunit mayroong isang mas simple at mas maliwanag na halimbawa sa Java java.util.logging:
import java.util.logging.*;
class Main {
  public static void main(String[] args) {
    Logger logger = Logger.getLogger(Main.class.getName());
    ConsoleHandler consoleHandler = new ConsoleHandler(){
		@Override
            public void publish(LogRecord record) {
                System.out.println("LogRecord обработан");
            }
        };
    logger.addHandler(consoleHandler);
    logger.info("test");
  }
}
Gaya ng nakikita mo, ang mga Handler ay idinaragdag sa listahan ng mga logger handler. Kapag ang isang logger ay nakatanggap ng mensahe para sa pagproseso, ang bawat naturang mensahe ay dumadaan sa isang hanay ng mga humahawak (mula sa logger.getHandlers) ​​para sa logger na iyon. Ang isa pang pattern na nakikita natin araw-araw ay " Iterator ". Ang kakanyahan nito ay ang paghiwalayin ang isang koleksyon ng mga bagay (i.e. isang klase na kumakatawan sa isang istraktura ng data. Halimbawa, List) at ang paglalakbay ng koleksyon na ito.
import java.util.*;
class Main {
  public static void main(String[] args) {
    List<String> data = Arrays.asList("Moscow", "Paris", "NYC");
    Iterator<String> iterator = data.iterator();
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}
Tulad ng nakikita mo, ang iterator ay hindi bahagi ng koleksyon, ngunit kinakatawan ng isang hiwalay na klase na dumadaan sa koleksyon. Maaaring hindi alam ng user ng iterator kung anong koleksyon ang inuulit nito, i.e. anong collection ang binibisita niya? Ito ay nagkakahalaga ng pagsasaalang-alang sa pattern ng " Bisita ". Ang pattern ng bisita ay halos kapareho sa pattern ng iterator. Tinutulungan ka ng pattern na ito na i-bypass ang istraktura ng mga bagay at magsagawa ng mga aksyon sa mga bagay na ito. Magkaiba sila sa konsepto. Binabaybay ng iterator ang koleksyon upang ang kliyente na gumagamit ng iterator ay walang pakialam kung ano ang nasa loob ng koleksyon, tanging ang mga elemento sa pagkakasunud-sunod ang mahalaga. Ang ibig sabihin ng bisita ay mayroong isang tiyak na hierarchy o istraktura ng mga bagay na binibisita namin. Halimbawa, maaari naming gamitin ang hiwalay na pagpoproseso ng direktoryo at hiwalay na pagproseso ng file. Ang Java ay may out-of-the-box na pagpapatupad ng pattern na ito sa anyo java.nio.file.FileVisitor:
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.*;
class Main {
  public static void main(String[] args) {
    SimpleFileVisitor visitor = new SimpleFileVisitor() {
      @Override
      public FileVisitResult visitFile(Object file, BasicFileAttributes attrs) throws IOException {
        System.out.println("File:" + file.toString());
        return FileVisitResult.CONTINUE;
      }
    };
    Path pathSource = Paths.get(System.getProperty("java.io.tmpdir"));
    try {
      Files.walkFileTree(pathSource, visitor);
    } catch (AccessDeniedException e) {
      // skip
    } catch (IOException e) {
      // Do something
    }
  }
}
Minsan may pangangailangan para sa ilang mga bagay na tumugon sa mga pagbabago sa iba pang mga bagay, at pagkatapos ay ang pattern na "Observer" ay makakatulong sa atin . Ang pinaka-maginhawang paraan ay ang magbigay ng mekanismo ng subscription na nagbibigay-daan sa ilang bagay na subaybayan at tumugon sa mga kaganapang nagaganap sa ibang mga bagay. Ang pattern na ito ay kadalasang ginagamit sa iba't ibang Tagapakinig at Tagamasid na tumutugon sa iba't ibang mga kaganapan. Bilang isang simpleng halimbawa, maaalala natin ang pagpapatupad ng pattern na ito mula sa unang bersyon ng JDK:
import java.util.*;
class Main {
  public static void main(String[] args) {
    Observer observer = (obj, arg) -> {
      System.out.println("Arg: " + arg);
    };
    Observable target = new Observable(){
      @Override
      public void notifyObservers(Object arg) {
        setChanged();
        super.notifyObservers(arg);
      }
    };
    target.addObserver(observer);
    target.notifyObservers("Hello, World!");
  }
}
May isa pang kapaki-pakinabang na pattern ng pag-uugali - " Tagapamagitan ". Ito ay kapaki-pakinabang dahil sa mga kumplikadong sistema nakakatulong ito upang alisin ang koneksyon sa pagitan ng iba't ibang mga bagay at italaga ang lahat ng mga pakikipag-ugnayan sa pagitan ng mga bagay sa ilang bagay, na isang tagapamagitan. Isa sa mga pinaka-kapansin-pansin na application ng pattern na ito ay Spring MVC, na gumagamit ng pattern na ito. Maaari mong basahin ang higit pa tungkol dito: " Spring: Mediator Pattern ". Madalas mong makikita ang parehong sa mga halimbawa java.util.Timer:
import java.util.*;
class Main {
  public static void main(String[] args) {
    Timer mediator = new Timer("Mediator");
    TimerTask command = new TimerTask() {
      @Override
      public void run() {
        System.out.println("Command pattern");
        mediator.cancel();
      }
    };
    mediator.schedule(command, 1000);
  }
}
Ang halimbawa ay mas mukhang isang command pattern. At ang kakanyahan ng pattern na "Mediator" ay nakatago sa pagpapatupad ng Timer'a. Sa loob ng timer ay may pila ng gawain TaskQueue, mayroong isang thread TimerThread. Kami, bilang mga kliyente ng klase na ito, ay hindi nakikipag-ugnayan sa kanila, ngunit nakikipag-ugnayan sa Timerbagay, na, bilang tugon sa aming tawag sa mga pamamaraan nito, ina-access ang mga pamamaraan ng iba pang mga bagay kung saan ito ay isang tagapamagitan. Sa panlabas, ito ay maaaring mukhang halos kapareho sa "Facade". Ngunit ang pagkakaiba ay kapag ginamit ang isang Facade, ang mga bahagi ay hindi alam na ang harapan ay umiiral at nakikipag-usap sa isa't isa. At kapag ginamit ang "Mediator", alam at ginagamit ng mga bahagi ang tagapamagitan, ngunit hindi direktang nakikipag-ugnayan sa isa't isa. Ito ay nagkakahalaga ng pagsasaalang-alang sa pattern na " Paraan ng Template ". Ang pattern ay malinaw mula sa pangalan nito. Ang ilalim na linya ay ang code ay nakasulat sa paraang ang mga user ng code (mga developer) ay binibigyan ng ilang template ng algorithm, ang mga hakbang kung saan pinapayagang muling tukuyin. Binibigyang-daan nito ang mga user ng code na huwag isulat ang buong algorithm, ngunit mag-isip lamang tungkol sa kung paano isagawa nang tama ang isa o isa pang hakbang ng algorithm na ito. Halimbawa, ang Java ay may abstract na klase AbstractListna tumutukoy sa pag-uugali ng isang iterator sa pamamagitan ng List. Gayunpaman, ang iterator mismo ay gumagamit ng mga pamamaraan ng dahon tulad ng: get, set, remove. Ang pag-uugali ng mga pamamaraang ito ay tinutukoy ng nag-develop ng mga inapo AbstractList. Kaya, ang iterator sa AbstractList- ay isang template para sa algorithm para sa pag-ulit sa isang sheet. At AbstractListbinabago ng mga developer ng mga partikular na pagpapatupad ang pag-uugali ng pag-ulit na ito sa pamamagitan ng pagtukoy sa gawi ng mga partikular na hakbang. Ang huli sa mga pattern na sinusuri namin ay ang pattern na " Snapshot " (Momento). Ang kakanyahan nito ay upang mapanatili ang isang tiyak na estado ng isang bagay na may kakayahang ibalik ang estado na ito. Ang pinakakilalang halimbawa mula sa JDK ay object serialization, i.e. java.io.Serializable. Tingnan natin ang isang halimbawa:
import java.io.*;
import java.util.*;
class Main {
  public static void main(String[] args) throws IOException {
    ArrayList<String> list = new ArrayList<>();
    list.add("test");
    // Save State
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    try (ObjectOutputStream out = new ObjectOutputStream(stream)) {
      out.writeObject(list);
    }
    // Load state
    byte[] bytes = stream.toByteArray();
    InputStream inputStream = new ByteArrayInputStream(bytes);
    try (ObjectInputStream in = new ObjectInputStream(inputStream)) {
      List<String> listNew = (List<String>) in.readObject();
      System.out.println(listNew.get(0));
    } catch (ClassNotFoundException e) {
      // Do something. Can't find class fpr saved state
    }
  }
}
Mga Pattern ng Disenyo sa Java - 8

Konklusyon

Tulad ng nakita natin mula sa pagsusuri, mayroong isang malaking iba't ibang mga pattern. Ang bawat isa sa kanila ay malulutas ang sarili nitong problema. At ang kaalaman sa mga pattern na ito ay makakatulong sa iyo na maunawaan sa tamang oras kung paano isulat ang iyong system upang ito ay flexible, mapanatili at lumalaban sa pagbabago. At panghuli, ilang link para sa mas malalim na pagsisid: #Viacheslav
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION