JavaRush /Блоги Java /Random-TG /Намунаи тарроҳии "Стратегия"

Намунаи тарроҳии "Стратегия"

Дар гурӯҳ нашр шудааст
Салом! Дар лекцияхои пештара мо бо чунин мафхум, монанди «накши тарроҳӣ» дучор шуда будем. Агар шумо фаромӯш карда бошед, биёед ба шумо хотиррасон кунем: ин истилоҳ ҳалли муайяни стандартиро барои як масъалаи умумӣ дар барномасозӣ ифода мекунад. Намунаи тарроҳии «Стратегия» - 1Дар JavaRush мо аксар вақт мегӯем, ки ҷавоб ба қариб ҳама саволҳоро метавон Google кард. Аз ин рӯ, эҳтимолан касе мушкилоти ба шумо монандро бомуваффақият ҳал кардааст. Ҳамин тавр, намунаҳо ҳалли вақт ва амалия санҷидашуда барои мушкилот ё усулҳои маъмултарини ҳалли вазъиятҳои мушкилот мебошанд. Инҳо ҳамон "велосипедҳо" ҳастанд, ки дар ҳеҷ сурат ба шумо худат ихтироъ кардан лозим нест, аммо шумо бояд бидонед, ки чӣ гуна ва кай онҳоро истифода бурдан лозим аст :) Вазифаи дигари намунаҳо ин аст, ки меъморӣ ба стандарти ягона оварда шавад. Хондани рамзи ягон кас кори осон нест! Хар кас ба таври гуногун менависад, зеро як масъаларо аз бисьёр чихат хал кардан мумкин аст. Аммо истифодаи намунаҳо ба барномасозони гуногун имкон медиҳад, ки мантиқи барномаро бидуни таваҷҷуҳ ба ҳар як сатри code дарк кунанд (ҳатто агар онҳо онро бори аввал бубинанд!) Имрӯз мо яке аз маъмултарин намунаҳоро бо номи “Стратегия” дида мебароем. Намунаи тарҳрезии "Стратегия" - 2Тасаввур кунем, ки мо барномае менависем, ки бо an objectи Car фаъолона кор мекунад. Дар ин ҳолат, ҳатто муҳим нест, ки барномаи мо маҳз чӣ кор мекунад. Барои ин, мо системаи меросро бо як синфи волидайн Autoва се синфҳои кӯдакона эҷод кардем: Sedan, Truckва F1Car.
public class Auto {

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {

       System.out.println("Тормозим!");
   }
}

public class Sedan extends Auto {
}

public class Truck extends Auto {
}

public class F1Car extends Auto {
}
Ҳар се синфи кӯдакон ду усули стандартиро аз волидайн мерос мегиранд - gas()ва stop() барномаи мо хеле содда аст: мошинҳо метавонанд танҳо ба пеш ҳаракат кунанд ва тормоз кунанд. Корамонро давом дода, карор додем, ки ба мошинхо усули нав — fill()(сузишворй) зам кунем. Биёед онро ба синфи волидайн илова кунем Auto:
public class Auto {

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {

       System.out.println("Тормозим!");
   }

   public void fill() {
       System.out.println("Заправить бензин!");
   }
}
Чунин ба назар мерасид, ки дар чунин вазъияти оддӣ мушкилот ба миён омада метавонанд? Хуб, дар асл, онҳо аллакай ба вуҷуд омадаанд ... Намунаи тарроҳии «Стратегия» - 3
public class ChildrenBuggies extends Auto {

   public void fill() {

       //хм... Это детский багги, его не надо заправлять :/
   }
}
Дар барномаи мо мошине пайдо шуд, ки ба концепцияи умумй — багги бачагона мувофик нест. Он метавонад бо педаль идора карда шавад ё бо радио идора карда шавад, аммо як чиз аниқ аст, ки дар он ҷо бензин андохтан нест. Схемаи мероси мо ба он оварда расонд, ки мо усулҳои маъмулро ҳатто ба синфҳое, ки ба онҳо эҳтиёҷ надоранд, додем. Дар чунин вазъият мо бояд чӣ кор кунем? Хуб, масалан, шумо метавонед ин усулро fill()дар синф бекор кунед ChildrenBuggies, то вақте ки шумо кӯшиш кунед, ки ба баги сӯзишворӣ пур кунед, ҳеҷ чиз рӯй надиҳад:
public class ChildrenBuggies extends Auto {

   @Override
   public void fill() {
       System.out.println("Игрушечную машину нельзя заправить!");
   }
}
Аммо ин ҳалли мушкилотро бомуваффақият номидан мумкин нест, ҳадди аққал аз сабаби такрори code. Масалан, аксари синфҳо усули синфи волидайнро истифода мебаранд, аммо синфҳои дигар маҷбур мешаванд, ки онро бекор кунанд. Агар мо 15 синф дошта бошем, ва дар 5-6 мо маҷбур мешавем, ки рафторро аз байн барем, такрори code хеле васеъ мешавад. Шояд интерфейсҳо ба мо кӯмак расонанд? Масалан, ин:
public interface Fillable {

   public void fill();
}
FillableМо бо як усул интерфейс эҷод мекунем fill(). Мутаносибан, он мошинҳое, ки бояд сӯзишворӣ пур карда шаванд, ин интерфейсро иҷро мекунанд, аммо мошинҳои дигар (масалан, мошини мо) ин корро намекунанд. Аммо ин вариант ба мо ҳам мувофиқат намекунад. Иерархияи синфии мо дар оянда метавонад ба шумораи хеле зиёд афзоиш ёбад (тасаввур кунед, ки дар ҷаҳон чанд намуди мошинҳо мавҷуданд). Мо варианти мероси қаблиро тарк кардем, зеро намехостем, ки fill(). Дар ин ҷо мо бояд онро дар ҳар синф татбиқ кунем! Чӣ мешавад, агар мо 50 нафари онҳоро дошта бошем? Ва агар ба барномаи мо зуд-зуд тағирот ворид карда шавад (ва дар барномаҳои воқеӣ ин тақрибан ҳамеша рӯй медиҳад!), мо бояд дар байни ҳамаи 50 синф забонамонро овезон давида, рафтори ҳар яки онҳоро дастӣ тағир диҳем. Пас, дар ниҳоят мо бояд чӣ кор кунем? Барои ҳалли мушкor худ, биёед роҳи дигарро интихоб кунем. Махз, биёед рафтори синфамонро аз худи синф чудо кунем. Ин чӣ маъно дорад? Тавре ки шумо медонед, ҳар як an object дорои ҳолат (маҷмӯи маълумот) ва рафтор (маҷмӯи усулҳо). Рафтори синфи мошинии мо аз се усул иборат аст - gas(), stop()ва fill(). Ду усули аввал хубанд. Аммо мо усули сеюмро берун аз синф мегузаронем Auto. Ин аз синф ҷудо кардани рафтор хоҳад буд (аниқтараш, мо танҳо як қисми рафторро ҷудо мекунем - ду усули аввал дар ҷои худ мемонанд). Мо бояд усули худро ба куҷо интиқол диҳем fill()? Дархол чизе ба хотир намеояд:/ У гуё тамоман дар чои худаш буд. Мо онро ба интерфейси алоҳида интиқол медиҳем - FillStrategy!
public interface FillStrategy {

   public void fill();
}
Чаро ба мо ин интерфейс лозим аст? Ин оддӣ аст. Акнун мо метавонем якчанд синфҳоро эҷод кунем, ки ин интерфейсро амалӣ мекунанд:
public class HybridFillStrategy implements FillStrategy {

   @Override
   public void fill() {
       System.out.println("Заправляем бензином or электричеством на выбор!");
   }
}

public class F1PitstopStrategy implements FillStrategy {

   @Override
   public void fill() {
       System.out.println("Заправляем бензин только после всех остальных procedures пит-стопа!");
   }
}

public class StandartFillStrategy implements FillStrategy {
   @Override
   public void fill() {
       System.out.println("Просто заправляем бензин!");
   }
}
Мо се стратегияи рафторро таҳия кардем - барои мошинҳои муқаррарӣ, гибридҳо ва мошинҳои Формула 1. Ҳар як стратегия алгоритми алоҳидаи сӯзишвориро амалӣ мекунад. Дар ҳолати мо, ин танҳо ба консол бароварда мешавад, аммо дар дохor усул метавонад мантиқи мураккаб мавҷуд бошад. Дар оянда мо бояд бо ин чӣ кор кунем?
public class Auto {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }

}
Мо интерфейси худро FillStrategyҳамчун майдон дар синфи волидайн истифода мебарем Auto. Лутфан таваҷҷӯҳ намоед: мо татбиқи мушаххасро муайян намекунем, балки интерфейсро истифода мебарем. Ва мо ба татбиқи мушаххаси интерфейс FillStrategyдар синфҳои мошинҳои кӯдакон ниёз дорем:
public class F1Car extends Auto {

   public F1Car() {
       this.fillStrategy = new F1PitstopStrategy();
   }
}

public class HybridAuto extends Auto {

   public HybridAuto() {
       this.fillStrategy = new HybridFillStrategy();
   }
}

public class Sedan extends Auto {

   public Sedan() {
       this.fillStrategy = new StandartFillStrategy();
   }
}
Биёед бубинем, ки мо чӣ дорем:
public class Main {

   public static void main(String[] args) {

       Auto sedan = new Sedan();
       Auto hybrid = new HybridAuto();
       Auto f1car = new F1Car();

       sedan.fill();
       hybrid.fill();
       f1car.fill();
   }
}
Натиҷаи консол:

Просто заправляем бензин!
Заправляем бензином or электричеством на выбор!
Заправляем бензин только после всех остальных procedures пит-стопа!
Аҷоиб, раванди пуркунии сӯзишворӣ тавре кор мекунад, ки бояд бошад! Дар омади гап, чизе ба мо халал намерасонад, ки стратегияро ҳамчун параметр дар конструктор истифода барем! Масалан, ба ин монанд:
public class Auto {

   private FillStrategy fillStrategy;

   public Auto(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }

   public void fill() {
       this.fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }
}

public class Sedan extends Auto {

   public Sedan() {
       super(new StandartFillStrategy());
   }
}



public class HybridAuto extends Auto {

   public HybridAuto() {
       super(new HybridFillStrategy());
   }
}

public class F1Car extends Auto {

   public F1Car() {
       super(new F1PitstopStrategy());
   }
}
Биёед усули худро иҷро кунем main()(он бетағйир мемонад) ва ҳамон натиҷаро ба даст орем! Натиҷаи консол:

Просто заправляем бензин!
Заправляем бензином or электричеством на выбор!
Заправляем бензин только после всех остальных procedures пит-стопа!
Намунаи Стратегия як оилаи алгоритмҳоро муайян мекунад, ҳар яки онҳоро фаро мегирад ва ивазшаванда будани онҳоро кафолат медиҳад. Он ба шумо имкон медиҳад, ки алгоритмҳоро новобаста аз истифодаи онҳо дар тарафи муштарӣ тағир диҳед (ин таъриф аз китоби "Таҳқиқи намунаҳои тарроҳӣ" гирифта шудааст ва ба назари ман хеле муваффақ ба назар мерасад). Намунаи тарроҳии «Стратегия» - 4Мо оилаи алгоритмҳоеро, ки ба мо таваҷҷӯҳ доранд (намудҳои мошинҳои сӯзишворӣ) ба интерфейсҳои алоҳида бо якчанд татбиқ ҷудо кардем. Мо онхоро аз худи мохияти мошин чудо кардем. Бинобар ин хозир, агар ба ин ё он процесси пур кардани сузишворй ягон тагьирот даровардан лозим бошад, ин ба классхои мо-шинхои мо хеч гуна таъсир намерасонад. Дар мавриди ивазкунӣ, барои ноил шудан ба он мо бояд танҳо як усули танзимкунандаро ба синфи худ илова кунем Auto:
public class Auto {

   FillStrategy fillStrategy;

   public void fill() {
       fillStrategy.fill();
   }

   public void gas() {
       System.out.println("Едем вперед");
   }

   public void stop() {
       System.out.println("Тормозим!");
   }

   public void setFillStrategy(FillStrategy fillStrategy) {
       this.fillStrategy = fillStrategy;
   }
}
Акнун мо метавонем стратегияҳоро зуд тағир диҳем:
public class Main {

   public static void main(String[] args) {

       ChildrenBuggies buggies = new ChildrenBuggies();
       buggies.setFillStrategy(new StandartFillStrategy());

       buggies.fill();
   }
}
Агар ногаҳон мошинҳои аробакаши кӯдакона бо бензин пур шаванд, барномаи мо ба чунин сенария омода мешавад :) Ҳамааш, дар асл! Шумо намунаи дигари тарроҳиро омӯхтед, ки бешубҳа ба шумо лозим меояд ва ҳангоми кор дар лоиҳаҳои воқеӣ ба шумо зиёда аз як маротиба кӯмак хоҳад кард :) Боз дидан!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION