Chào các em, chủ đề hôm nay của anh sẽ bàn về Design PatternBuilder ? Khi nào chúng ta sẽ dùng nó trong lập trình.
Khi nào nên dùng Builder pattern
Phương án 1 : Object có nhiều constructor. Sẽ có những trường hợp ta lấy 1 Class có rất nhiều constructor khởi tạo đối tượng. Ví dụ như lớp Pizza Sau đây
1 class có nhiều constructor với có nhiều parameter trong constructor sẽ gây khó khăn cho người lập trình để nhớ và sử dụng cái nào cho đúng. Cái này thì gọi là Telescoping Constructor
Có một cách để tránh Telescope là minh tạo tạo một object từ một constructor mặc định , sau đó dùng các hàm setter để set giá trị như ví dụ sau:
Phương án 2 : Khi chúng ta muốn tạo object được cấu thành từ nhiều phần khác nhau. Khác với abstract factory chúng ta muốn build 1 bộ sản phẩm giống như xe Toyota gồm có lốp Toyota, phanh Toyota. ect Toyota. Thì Builder được sử dụng khi ta muốn build 1 sản phẩm từ nhiều bộ phận khác nhau như xe Toyota, phay Huynhdai , lốp Ferrary
Builder UML pattern
Builder Java Code
1
2
3
4
5
6
7
8
9
10
11
/**
* Builder interface defines all possible ways to configure a product.
*/publicinterfaceBuilder{voidsetType(Typetype);voidsetSeats(intseats);voidsetEngine(Engineengine);voidsetTransmission(Transmissiontransmission);voidsetTripComputer(TripComputertripComputer);voidsetGPSNavigator(GPSNavigatorgpsNavigator);}
/**
* Concrete builders implement steps defined in the common interface.
*/publicclassCarBuilderimplementsBuilder{privateTypetype;privateintseats;privateEngineengine;privateTransmissiontransmission;privateTripComputertripComputer;privateGPSNavigatorgpsNavigator;@OverridepublicvoidsetType(Typetype){this.type=type;}@OverridepublicvoidsetSeats(intseats){this.seats=seats;}@OverridepublicvoidsetEngine(Engineengine){this.engine=engine;}@OverridepublicvoidsetTransmission(Transmissiontransmission){this.transmission=transmission;}@OverridepublicvoidsetTripComputer(TripComputertripComputer){this.tripComputer=tripComputer;}@OverridepublicvoidsetGPSNavigator(GPSNavigatorgpsNavigator){this.gpsNavigator=gpsNavigator;}publicCargetResult(){returnnewCar(type,seats,engine,transmission,tripComputer,gpsNavigator);}}
/**
* Unlike other creational patterns, Builder can construct unrelated products,
* which don't have the common interface.
*
* In this case we build a user manual for a car, using the same steps as we
* built a car. This allows to produce manuals for specific car models,
* configured with different features.
*/publicclassCarManualBuilderimplementsBuilder{privateTypetype;privateintseats;privateEngineengine;privateTransmissiontransmission;privateTripComputertripComputer;privateGPSNavigatorgpsNavigator;@OverridepublicvoidsetType(Typetype){this.type=type;}@OverridepublicvoidsetSeats(intseats){this.seats=seats;}@OverridepublicvoidsetEngine(Engineengine){this.engine=engine;}@OverridepublicvoidsetTransmission(Transmissiontransmission){this.transmission=transmission;}@OverridepublicvoidsetTripComputer(TripComputertripComputer){this.tripComputer=tripComputer;}@OverridepublicvoidsetGPSNavigator(GPSNavigatorgpsNavigator){this.gpsNavigator=gpsNavigator;}publicManualgetResult(){returnnewManual(type,seats,engine,transmission,tripComputer,gpsNavigator);}}
/**
* Director defines the order of building steps. It works with a builder object
* through common Builder interface. Therefore it may not know what product is
* being built.
*/publicclassDirector{publicvoidconstructSportsCar(Builderbuilder){builder.setType(Type.SPORTS_CAR);builder.setSeats(2);builder.setEngine(newEngine(3.0,0));builder.setTransmission(Transmission.SEMI_AUTOMATIC);builder.setTripComputer(newTripComputer());builder.setGPSNavigator(newGPSNavigator());}publicvoidconstructCityCar(Builderbuilder){builder.setType(Type.CITY_CAR);builder.setSeats(2);builder.setEngine(newEngine(1.2,0));builder.setTransmission(Transmission.AUTOMATIC);builder.setTripComputer(newTripComputer());builder.setGPSNavigator(newGPSNavigator());}publicvoidconstructSUV(Builderbuilder){builder.setType(Type.SUV);builder.setSeats(4);builder.setEngine(newEngine(2.5,0));builder.setTransmission(Transmission.MANUAL);builder.setGPSNavigator(newGPSNavigator());}}
/**
* Demo class. Everything comes together here.
*/publicclassDemo{publicstaticvoidmain(String[]args){Directordirector=newDirector();// Director gets the concrete builder object from the client// (application code). That's because application knows better which// builder to use to get a specific product.CarBuilderbuilder=newCarBuilder();director.constructSportsCar(builder);// The final product is often retrieved from a builder object, since// Director is not aware and not dependent on concrete builders and// products.Carcar=builder.getResult();System.out.println("Car built:\n"+car.getType());CarManualBuildermanualBuilder=newCarManualBuilder();// Director may know several building recipes.director.constructSportsCar(manualBuilder);ManualcarManual=manualBuilder.getResult();System.out.println("\nCar manual built:\n"+carManual.print());}}
/**
* Car is a product class.
*/publicclassCar{privatefinalTypetype;privatefinalintseats;privatefinalEngineengine;privatefinalTransmissiontransmission;privatefinalTripComputertripComputer;privatefinalGPSNavigatorgpsNavigator;privatedoublefuel=0;publicCar(Typetype,intseats,Engineengine,Transmissiontransmission,TripComputertripComputer,GPSNavigatorgpsNavigator){this.type=type;this.seats=seats;this.engine=engine;this.transmission=transmission;this.tripComputer=tripComputer;this.tripComputer.setCar(this);this.gpsNavigator=gpsNavigator;}publicTypegetType(){returntype;}publicdoublegetFuel(){returnfuel;}publicvoidsetFuel(doublefuel){this.fuel=fuel;}publicintgetSeats(){returnseats;}publicEnginegetEngine(){returnengine;}publicTransmissiongetTransmission(){returntransmission;}publicTripComputergetTripComputer(){returntripComputer;}publicGPSNavigatorgetGpsNavigator(){returngpsNavigator;}}