Kiến trúc và thiết kế phần mềm

pdf 55 trang Gia Huy 17/05/2022 2670
Bạn đang xem 20 trang mẫu của tài liệu "Kiến trúc và thiết kế phần mềm", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfkien_truc_va_thiet_ke_phan_mem.pdf

Nội dung text: Kiến trúc và thiết kế phần mềm

  1. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG 🙞�🙞 Kiến trúc và thiết kế phần mềm Hà Nội, tháng 05, năm 2021 1.Factory Pattern:
  2. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT UML Một Factory Pattern bao gồm các thành phần cơ bản sau: Super Class: môt supper class trong Factory Pattern có thể là một interface, abstract class hay một class thông thường. Sub Classes: các sub class sẽ implement các phương thức của supper class theo nghiệp vụ riêng của nó. Factory Class: một class chịu tránh nhiệm khởi tạo các đối tượng sub class dựa theo tham số đầu vào. Lưu ý: lớp này là Singleton hoặc cung cấp một public static method cho việc truy xuất và khởi tạo đối tượng. Factory class sử dụng if-else hoặc switch-case để xác định class con đầu ra. Code: Bước 1 Tạo giao diện. Shape.java public interface Shape { void draw(); } Bước 2
  3. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Tạo các lớp cụ thể triển khai cùng một giao diện. Rectangle.java public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } } Square.java public class Square implements Shape { @Override public void draw() { System.out.println("Inside Square::draw() method."); } } Circle.java public class Circle implements Shape { @Override public void draw() { System.out.println("Inside Circle::draw() method."); } } Bước 3 Tạo một Nhà máy để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho. ShapeFactory.java public class ShapeFactory { //use getShape method to get object of type shape public Shape getShape(String shapeType){ if(shapeType == null){ return null; } if(shapeType.equalsIgnoreCase("CIRCLE")){ return new Circle(); } else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle();
  4. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } } Bước 4 Sử dụng Factory để lấy đối tượng của lớp cụ thể bằng cách chuyển một thông tin như kiểu. FactoryPatternDemo.java public class FactoryPatternDemo { public static void main(String[] args) { ShapeFactory shapeFactory = new ShapeFactory(); //get an object of Circle and call its draw method. Shape shape1 = shapeFactory.getShape("CIRCLE"); //call draw method of Circle shape1.draw(); //get an object of Rectangle and call its draw method. Shape shape2 = shapeFactory.getShape("RECTANGLE"); //call draw method of Rectangle shape2.draw(); //get an object of Square and call its draw method. Shape shape3 = shapeFactory.getShape("SQUARE"); //call draw method of square shape3.draw(); } } Bước 5 Xác minh kết quả đầu ra. Inside Circle::draw() method. Inside Rectangle::draw() method. Inside Square::draw() method.
  5. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT 2. ABSTRACT FACTORY PATTERN UML Một Abstract Factory Pattern bao gồm các thành phần cơ bản sau: AbstractFactory: Khai báo dạng interface hoặc abstract class chứa các phương thức để tạo ra các đối tượng abstract. ConcreteFactory: Xây dựng, cài đặt các phương thức tạo các đối tượng cụ thể. AbstractProduct: Khai báo dạng interface hoặc abstract class để định nghĩa đối tượng abstract. Product: Cài đặt của các đối tượng cụ thể, cài đặt các phương thức được quy định tại AbstractProduct. Client: là đối tượng sử dụng AbstractFactory và các AbstractProduct. Code:
  6. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Bước 1 Tạo giao diện cho Shapes. Shape.java public interface Shape { void draw(); } Bước 2 Tạo các lớp cụ thể triển khai cùng một giao diện. RoundedRectangle.java public class RoundedRectangle implements Shape { @Override public void draw() { System.out.println("Inside RoundedRectangle::draw() method."); } } RoundedSquare.java public class RoundedSquare implements Shape { @Override public void draw() { System.out.println("Inside RoundedSquare::draw() method."); } } Rectangle.java public class Rectangle implements Shape { @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } } Bước 3 Tạo một lớp Trừu tượng để lấy các nhà máy cho các Đối tượng Hình dạng Thường và Hình tròn. AbstractFactory.java public abstract class AbstractFactory {
  7. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT abstract Shape getShape(String shapeType) ; } Bước 4 Tạo các lớp Factory mở rộng AbstractFactory để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho. ShapeFactory.java public class ShapeFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle(); }else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square(); } return null; } } RoundedShapeFactory.java public class RoundedShapeFactory extends AbstractFactory { @Override public Shape getShape(String shapeType){ if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new RoundedRectangle(); }else if(shapeType.equalsIgnoreCase("SQUARE")){ return new RoundedSquare(); } return null; } } Bước 5 Tạo một lớp Nhà máy sản xuất / nhà sản xuất để nhận các nhà máy bằng cách chuyển một thông tin chẳng hạn như Hình dạng FactoryProductioner.java public class FactoryProducer { public static AbstractFactory getFactory(boolean rounded){ if(rounded){ return new RoundedShapeFactory(); }else{ return new ShapeFactory();
  8. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } } } Bước 6 Sử dụng FactoryProductioner để lấy AbstractFactory để lấy các nhà máy của các lớp cụ thể bằng cách chuyển một thông tin chẳng hạn như loại. AbstractFactoryPatternDemo.java public class AbstractFactoryPatternDemo { public static void main(String[] args) { //get shape factory AbstractFactory shapeFactory = FactoryProducer.getFactory(false); //get an object of Shape Rectangle Shape shape1 = shapeFactory.getShape("RECTANGLE"); //call draw method of Shape Rectangle shape1.draw(); //get an object of Shape Square Shape shape2 = shapeFactory.getShape("SQUARE"); //call draw method of Shape Square shape2.draw(); //get shape factory AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true); //get an object of Shape Rectangle Shape shape3 = shapeFactory1.getShape("RECTANGLE"); //call draw method of Shape Rectangle shape3.draw(); //get an object of Shape Square Shape shape4 = shapeFactory1.getShape("SQUARE"); //call draw method of Shape Square shape4.draw(); } } Bước 7 Xác minh kết quả đầu ra. Inside Rectangle::draw() method. Inside Square::draw() method. Inside RoundedRectangle::draw() method. Inside RoundedSquare::draw() method.
  9. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT 3.Builder Pattern UML Một builder gồm các thành phần cơ bản sau: Product : đại diện cho đối tượng cần tạo, đối tượng này phức tạp, có nhiều thuộc tính. Builder : là abstract class hoặc interface khai báo phương thức tạo đối tượng. ConcreteBuilder : kế thừa Builder và cài đặt chi tiết cách tạo ra đối tượng. Nó sẽ xác định và nắm giữ các thể hiện mà nó tạo ra, đồng thời nó cũng cung cấp phương thức để trả các các thể hiện mà nó đã tạo ra trước đó. Director/ Client: là nơi sẽ gọi tới Builder để tạo ra đối tượng. Code: Bước 1 Tạo giao diện Mục đại diện cho mặt hàng thực phẩm và đóng gói. Item.java
  10. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public interface Item { public String name(); public Packing packing(); public float price(); } Packing.java public interface Packing { public String pack(); } Bước 2 Tạo các lớp cụ thể thực hiện giao diện Đóng gói. Wrapper.java public class Wrapper implements Packing { @Override public String pack() { return "Wrapper"; } } Bottle.java public class Bottle implements Packing { @Override public String pack() { return "Bottle"; } } Bước 3 Tạo các lớp trừu tượng triển khai giao diện mục cung cấp các chức năng mặc định. Burger.java public abstract class Burger implements Item { @Override public Packing packing() { return new Wrapper(); }
  11. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT @Override public abstract float price(); } ColdDrink.java public abstract class ColdDrink implements Item { @Override public Packing packing() { return new Bottle(); } @Override public abstract float price(); } Bước 4 Tạo các lớp cụ thể mở rộng các lớp Burger và ColdDrink VegBurger.java public class VegBurger extends Burger { @Override public float price() { return 25.0f; } @Override public String name() { return "Veg Burger"; } } ChickenBurger.java public class ChickenBurger extends Burger { @Override public float price() { return 50.5f; } @Override public String name() { return "Chicken Burger"; }
  12. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } Coke.java public class Coke extends ColdDrink { @Override public float price() { return 30.0f; } @Override public String name() { return "Coke"; } } Pepsi.java public class Pepsi extends ColdDrink { @Override public float price() { return 35.0f; } @Override public String name() { return "Pepsi"; } } Bước 5 Tạo một lớp Bữa ăn có các đối tượng Item được xác định ở trên. Meal.java import java.util.ArrayList; import java.util.List; public class Meal { private List items = new ArrayList (); public void addItem(Item item){ items.add(item); } public float getCost(){ float cost = 0.0f;
  13. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT for (Item item : items) { cost += item.price(); } return cost; } public void showItems(){ for (Item item : items) { System.out.print("Item : " + item.name()); System.out.print(", Packing : " + item.packing().pack()); System.out.println(", Price : " + item.price()); } } } Bước 6 Tạo một lớp MealBuilder, lớp người xây dựng thực tế chịu trách nhiệm tạo các đối tượng Bữa ăn. MealBuilder.java public class MealBuilder { public Meal prepareVegMeal (){ Meal meal = new Meal(); meal.addItem(new VegBurger()); meal.addItem(new Coke()); return meal; } public Meal prepareNonVegMeal (){ Meal meal = new Meal(); meal.addItem(new ChickenBurger()); meal.addItem(new Pepsi()); return meal; } } Bước 7 BuiderPatternDemo sử dụng MealBuider để chứng minh mẫu trình tạo. BuilderPatternDemo.java public class BuilderPatternDemo {
  14. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public static void main(String[] args) { MealBuilder mealBuilder = new MealBuilder(); Meal vegMeal = mealBuilder.prepareVegMeal(); System.out.println("Veg Meal"); vegMeal.showItems(); System.out.println("Total Cost: " + vegMeal.getCost()); Meal nonVegMeal = mealBuilder.prepareNonVegMeal(); System.out.println("\n\nNon-Veg Meal"); nonVegMeal.showItems(); System.out.println("Total Cost: " + nonVegMeal.getCost()); } } Bước 8 Xác minh kết quả đầu ra. Veg Meal Item : Veg Burger, Packing : Wrapper, Price : 25.0 Item : Coke, Packing : Bottle, Price : 30.0 Total Cost: 55.0 Non-Veg Meal Item : Chicken Burger, Packing : Wrapper, Price : 50.5 Item : Pepsi, Packing : Bottle, Price : 35.0 Total Cost: 85.5 4. PROTOTYPE PATTERN UML:
  15. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Một Prototype Pattern gồm các thành phần cơ bản sau: Prototype : khai báo một class, interface hoặc abtract class cho việc clone chính nó. ConcretePrototype class : các lớp này thực thi interface (hoặc kế thừa từ lớp abstract) được cung cấp bởi Prototype để copy (nhân bản) chính bản thân nó. Các lớp này chính là thể hiện cụ thể phương thức clone(). Lớp này có thể không cần thiết nếu: Prototype là một class và nó đã implement việc clone chính nó. Client class : tạo mới object bằng cách gọi Prototype thực hiện clone chính nó. Code: Bước 1 Tạo một lớp trừu tượng triển khai giao diện Clonable . Shape.java public abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType(){
  16. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } } Bước 2 Tạo các lớp cụ thể mở rộng lớp trên. Rectangle.java public class Rectangle extends Shape { public Rectangle(){ type = "Rectangle"; } @Override public void draw() { System.out.println("Inside Rectangle::draw() method."); } } Square.java public class Square extends Shape { public Square(){ type = "Square";
  17. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } @Override public void draw() { System.out.println("Inside Square::draw() method."); } } Circle.java public class Circle extends Shape { public Circle(){ type = "Circle"; } @Override public void draw() { System.out.println("Inside Circle::draw() method."); } } Bước 3 Tạo một lớp để lấy các lớp cụ thể từ cơ sở dữ liệu và lưu trữ chúng trong Hashtable . ShapeCache.java import java.util.Hashtable; public class ShapeCache { private static Hashtable shapeMap = new Hashtable (); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } // for each shape run database query and create shape // shapeMap.put(shapeKey, shape); // for example, we are adding three shapes public static void loadCache() { Circle circle = new Circle(); circle.setId("1"); shapeMap.put(circle.getId(),circle);
  18. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Square square = new Square(); square.setId("2"); shapeMap.put(square.getId(),square); Rectangle rectangle = new Rectangle(); rectangle.setId("3"); shapeMap.put(rectangle.getId(), rectangle); } } Bước 4 PrototypePatternDemo sử dụng lớp ShapeCache để lấy bản sao của các hình dạng được lưu trữ trong Hashtable . PrototypePatternDemo.java public class PrototypePatternDemo { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape = (Shape) ShapeCache.getShape("1"); System.out.println("Shape : " + clonedShape.getType()); Shape clonedShape2 = (Shape) ShapeCache.getShape("2"); System.out.println("Shape : " + clonedShape2.getType()); Shape clonedShape3 = (Shape) ShapeCache.getShape("3"); System.out.println("Shape : " + clonedShape3.getType()); } } Bước 5 Xác minh kết quả đầu ra. Shape : Circle Shape : Square Shape : Rectangle 5. PROXY PATTERN: Use case
  19. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Các thành phần tham gia vào mẫu Proxy Pattern: Subject : là một interface định nghĩa các phương thực để giao tiếp với client. Đối tượng này xác định giao diện chung cho RealSubject và Proxy để Proxy có thể được sử dụng bất cứ nơi nào mà RealSubject mong đợi. Proxy : là một class sẽ thực hiện các bước kiểm tra và gọi tới đối tượng của class service thật để thực hiện các thao tác sau khi kiểm tra. Nó duy trì một tham chiếu đến RealSubject để Proxy có thể truy cập nó. Nó cũng thực hiện các giao diện tương tự như RealSubject để Proxy có thể được sử dụng thay cho RealSubject. Proxy cũng điều khiển truy cập vào RealSubject và có thể tạo hoặc xóa đối tượng này. RealSubject : là một class service sẽ thực hiện các thao tác thực sự. Đây là đối tượng chính mà proxy đại diện. Client : Đối tượng cần sử dụng RealSubject nhưng thông qua Proxy. Code: Bước 1 Tạo giao diện. Image.java public interface Image { void display(); } Bước 2
  20. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Tạo các lớp cụ thể triển khai cùng một giao diện. RealImage.java public class RealImage implements Image { private String fileName; public RealImage(String fileName){ this.fileName = fileName; loadFromDisk(fileName); } @Override public void display() { System.out.println("Displaying " + fileName); } private void loadFromDisk(String fileName){ System.out.println("Loading " + fileName); } } ProxyImage.java public class ProxyImage implements Image{ private RealImage realImage; private String fileName; public ProxyImage(String fileName){ this.fileName = fileName; } @Override public void display() { if(realImage == null){ realImage = new RealImage(fileName); } realImage.display(); } } Bước 3 Sử dụng ProxyImage để lấy đối tượng của lớp RealImage khi được yêu cầu. ProxyPatternDemo.java public class ProxyPatternDemo {
  21. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public static void main(String[] args) { Image image = new ProxyImage("test_10mb.jpg"); //image will be loaded from disk image.display(); System.out.println(""); //image will not be loaded from disk image.display(); } } Bước 4 Xác minh kết quả đầu ra. Loading test_10mb.jpg Displaying test_10mb.jpg Displaying test_10mb.jpg 6. Bridge Pattern: UML: Một Bridge Pattern bao gồm các thành phần sau:
  22. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Client: đại diện cho khách hàng sử dụng các chức năng thông qua Abstraction. Abstraction : định ra một abstract interface quản lý việc tham chiếu đến đối tượng hiện thực cụ thể (Implementor). Refined Abstraction (AbstractionImpl) : hiện thực (implement) các phương thức đã được định ra trong Abstraction bằng cách sử dụng một tham chiếu đến một đối tượng của Implementer. Implementor : định ra các interface cho các lớp hiện thực. Thông thường nó là interface định ra các tác vụ nào đó của Abstraction. ConcreteImplementor : hiện thực Implementor interface. Code: Bước 1 Tạo giao diện trình triển khai cầu nối. DrawAPI.java public interface DrawAPI { public void drawCircle(int radius, int x, int y); } Bước 2 Tạo các lớp triển khai cầu bê tông thực hiện giao diện DrawAPI . RedCircle.java public class RedCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle[ color: red, radius: " + radius + ", x: " + x + ", " + y + "]"); } } GreenCircle.java public class GreenCircle implements DrawAPI { @Override public void drawCircle(int radius, int x, int y) { System.out.println("Drawing Circle[ color: green, radius: " + radius + ", x: " + x + ", " + y + "]"); } }
  23. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Bước 3 Tạo một hình dạng lớp trừu tượng bằng giao diện DrawAPI . Shape.java public abstract class Shape { protected DrawAPI drawAPI; protected Shape(DrawAPI drawAPI){ this.drawAPI = drawAPI; } public abstract void draw(); } Bước 4 Tạo lớp cụ thể thực hiện giao diện Shape . Circle.java public class Circle extends Shape { private int x, y, radius; public Circle(int x, int y, int radius, DrawAPI drawAPI) { super(drawAPI); this.x = x; this.y = y; this.radius = radius; } public void draw() { drawAPI.drawCircle(radius,x,y); } } Bước 5 Sử dụng các lớp Shape và DrawAPI để vẽ các vòng tròn màu khác nhau. BridgePatternDemo.java public class BridgePatternDemo { public static void main(String[] args) { Shape redCircle = new Circle(100,100, 10, new RedCircle()); Shape greenCircle = new Circle(100,100, 10, new GreenCircle()); redCircle.draw();
  24. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT greenCircle.draw(); } } Bước 6 Xác minh kết quả đầu ra. Drawing Circle[ color: red, radius: 10, x: 100, 100] Drawing Circle[ color: green, radius: 10, x: 100, 100] 7.Singleton Pattern: UML: Sử dụng Singleton khi chúng ta muốn: Đảm bảo rằng chỉ có một instance của lớp. Việc quản lý việc truy cập tốt hơn vì chỉ có một thể hiện duy nhất. Có thể quản lý số lượng thể hiện của một lớp trong giớn hạn chỉ định.
  25. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Code: Bước 1 Tạo một lớp Singleton. SingleObject.java public class SingleObject { //create an object of SingleObject private static SingleObject instance = new SingleObject(); //make the constructor private so that this class cannot be //instantiated private SingleObject(){} //Get the only object available public static SingleObject getInstance(){ return instance; } public void showMessage(){ System.out.println("Hello World!"); } } Bước 2 Lấy đối tượng duy nhất từ ​ ​ lớp singleton. SingletonPatternDemo.java public class SingletonPatternDemo { public static void main(String[] args) { //illegal construct //Compile Time Error: The constructor SingleObject() is not visible //SingleObject object = new SingleObject(); //Get the only object available SingleObject object = SingleObject.getInstance(); //show the message object.showMessage(); } }
  26. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Bước 3 Xác minh kết quả đầu ra. Hello World! 8. Flyweight Pattern UML: Code: Bước 1 Tạo giao diện. Shape.java public interface Shape { void draw(); } Bước 2
  27. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Tạo lớp cụ thể thực hiện cùng một giao diện. Circle.java public class Circle implements Shape { private String color; private int x; private int y; private int radius; public Circle(String color){ this.color = color; } public void setX(int x) { this.x = x; } public void setY(int y) { this.y = y; } public void setRadius(int radius) { this.radius = radius; } @Override public void draw() { System.out.println("Circle: Draw() [Color : " + color + ", x : " + x + ", y :" + y + ", radius :" + radius); } } Bước 3 Tạo một nhà máy để tạo đối tượng của lớp cụ thể dựa trên thông tin đã cho. ShapeFactory.java import java.util.HashMap; public class ShapeFactory { // Uncomment the compiler directive line and // javac *.java will compile properly. // @SuppressWarnings("unchecked") private static final HashMap circleMap = new HashMap(); public static Shape getCircle(String color) {
  28. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Circle circle = (Circle)circleMap.get(color); if(circle == null) { circle = new Circle(color); circleMap.put(color, circle); System.out.println("Creating circle of color : " + color); } return circle; } } Bước 4 Sử dụng nhà máy để lấy đối tượng của lớp bê tông bằng cách chuyển một thông tin chẳng hạn như màu sắc. FlyweightPatternDemo.java public class FlyweightPatternDemo { private static final String colors[] = { "Red", "Green", "Blue", "White", "Black" }; public static void main(String[] args) { for(int i=0; i < 20; ++i) { Circle circle = (Circle)ShapeFactory.getCircle(getRandomColor()); circle.setX(getRandomX()); circle.setY(getRandomY()); circle.setRadius(100); circle.draw(); } } private static String getRandomColor() { return colors[(int)(Math.random()*colors.length)]; } private static int getRandomX() { return (int)(Math.random()*100 ); } private static int getRandomY() { return (int)(Math.random()*100); } } Bước 5 Xác minh kết quả đầu ra. Creating circle of color : Black
  29. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Circle: Draw() [Color : Black, x : 36, y :71, radius :100 Creating circle of color : Green Circle: Draw() [Color : Green, x : 27, y :27, radius :100 Creating circle of color : White Circle: Draw() [Color : White, x : 64, y :10, radius :100 Creating circle of color : Red Circle: Draw() [Color : Red, x : 15, y :44, radius :100 Circle: Draw() [Color : Green, x : 19, y :10, radius :100 Circle: Draw() [Color : Green, x : 94, y :32, radius :100 Circle: Draw() [Color : White, x : 69, y :98, radius :100 Creating circle of color : Blue Circle: Draw() [Color : Blue, x : 13, y :4, radius :100 Circle: Draw() [Color : Green, x : 21, y :21, radius :100 Circle: Draw() [Color : Blue, x : 55, y :86, radius :100 Circle: Draw() [Color : White, x : 90, y :70, radius :100 Circle: Draw() [Color : Green, x : 78, y :3, radius :100 Circle: Draw() [Color : Green, x : 64, y :89, radius :100 Circle: Draw() [Color : Blue, x : 3, y :91, radius :100 Circle: Draw() [Color : Blue, x : 62, y :82, radius :100 Circle: Draw() [Color : Green, x : 97, y :61, radius :100 Circle: Draw() [Color : Green, x : 86, y :12, radius :100 Circle: Draw() [Color : Green, x : 38, y :93, radius :100 Circle: Draw() [Color : Red, x : 76, y :82, radius :100 Circle: Draw() [Color : Blue, x : 95, y :82, radius :100 9. Adapter Pattern: UML:
  30. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Một Adapter Pattern bao gồm các thành phần cơ bản sau: Adaptee: định nghĩa interface không tương thích, cần được tích hợp vào. Adapter: lớp tích hợp, giúp interface không tương thích tích hợp được với interface đang làm việc. Thực hiện việc chuyển đổi interface cho Adaptee và kết nối Adaptee với Client. Target: một interface chứa các chức năng được sử dụng bởi Client (domain specific). Client: lớp sử dụng các đối tượng có interface Target. Code: Bước 1 Tạo giao diện cho Media Player và Advanced Media Player. MediaPlayer.java public interface MediaPlayer { public void play(String audioType, String fileName); }
  31. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT AdvancedMediaPlayer.java public interface AdvancedMediaPlayer { public void playVlc(String fileName); public void playMp4(String fileName); } Bước 2 Tạo các lớp cụ thể triển khai giao diện AdvancedMediaPlayer . VlcPlayer.java public class VlcPlayer implements AdvancedMediaPlayer{ @Override public void playVlc(String fileName) { System.out.println("Playing vlc file. Name: "+ fileName); } @Override public void playMp4(String fileName) { //do nothing } } Mp4Player.java public class Mp4Player implements AdvancedMediaPlayer{ @Override public void playVlc(String fileName) { //do nothing } @Override public void playMp4(String fileName) { System.out.println("Playing mp4 file. Name: "+ fileName); } } Bước 3 Tạo lớp bộ điều hợp triển khai giao diện MediaPlayer . MediaAdapter.java public class MediaAdapter implements MediaPlayer { AdvancedMediaPlayer advancedMusicPlayer;
  32. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public MediaAdapter(String audioType){ if(audioType.equalsIgnoreCase("vlc") ){ advancedMusicPlayer = new VlcPlayer(); }else if (audioType.equalsIgnoreCase("mp4")){ advancedMusicPlayer = new Mp4Player(); } } @Override public void play(String audioType, String fileName) { if(audioType.equalsIgnoreCase("vlc")){ advancedMusicPlayer.playVlc(fileName); } else if(audioType.equalsIgnoreCase("mp4")){ advancedMusicPlayer.playMp4(fileName); } } } Bước 4 Tạo lớp cụ thể triển khai giao diện MediaPlayer . AudioPlayer.java public class AudioPlayer implements MediaPlayer { MediaAdapter mediaAdapter; @Override public void play(String audioType, String fileName) { //inbuilt support to play mp3 music files if(audioType.equalsIgnoreCase("mp3")){ System.out.println("Playing mp3 file. Name: " + fileName); } //mediaAdapter is providing support to play other file formats else if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){ mediaAdapter = new MediaAdapter(audioType); mediaAdapter.play(audioType, fileName); } else{
  33. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT System.out.println("Invalid media. " + audioType + " format not supported"); } } } Bước 5 Sử dụng Trình phát âm thanh để phát các loại định dạng âm thanh khác nhau. AdapterPatternDemo.java public class AdapterPatternDemo { public static void main(String[] args) { AudioPlayer audioPlayer = new AudioPlayer(); audioPlayer.play("mp3", "beyond the horizon.mp3"); audioPlayer.play("mp4", "alone.mp4"); audioPlayer.play("vlc", "far far away.vlc"); audioPlayer.play("avi", "mind me.avi"); } } Bước 6 Xác minh kết quả đầu ra. Playing mp3 file. Name: beyond the horizon.mp3 Playing mp4 file. Name: alone.mp4 Playing vlc file. Name: far far away.vlc Invalid media. avi format not supported 9. Composite Pattern: UML:
  34. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Một Composite Pattern bao gồm các thành phần cơ bản sau: Base Component : là một interface hoặc abstract class quy định các method chung cần phải có cho tất cả các thành phần tham gia vào mẫu này. Leaf : là lớp hiện thực (implements) các phương thức của Component. Nó là các object không có con. Composite : lưu trữ tập hợp các Leaf và cài đặt các phương thức của Base Component. Composite cài đặt các phương thức được định nghĩa trong interface Component bằng cách ủy nhiệm cho các thành phần con xử lý. Client: sử dụng Base Component để làm việc với các đối tượng trong Composite. Code: Bước 1 Tạo lớp Nhân viên có danh sách các đối tượng Nhân viên . Employee.java import java.util.ArrayList;
  35. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT import java.util.List; public class Employee { private String name; private String dept; private int salary; private List subordinates; // constructor public Employee(String name,String dept, int sal) { this.name = name; this.dept = dept; this.salary = sal; subordinates = new ArrayList (); } public void add(Employee e) { subordinates.add(e); } public void remove(Employee e) { subordinates.remove(e); } public List getSubordinates(){ return subordinates; } public String toString(){ return ("Employee :[ Name : " + name + ", dept : " + dept + ", salary :" + salary+" ]"); } } Bước 2 Sử dụng lớp Nhân viên để tạo và in hệ thống phân cấp nhân viên. CompositePatternDemo.java public class CompositePatternDemo { public static void main(String[] args) { Employee CEO = new Employee("John","CEO", 30000); Employee headSales = new Employee("Robert","Head Sales", 20000);
  36. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Employee headMarketing = new Employee("Michel","Head Marketing", 20000); Employee clerk1 = new Employee("Laura","Marketing", 10000); Employee clerk2 = new Employee("Bob","Marketing", 10000); Employee salesExecutive1 = new Employee("Richard","Sales", 10000); Employee salesExecutive2 = new Employee("Rob","Sales", 10000); CEO.add(headSales); CEO.add(headMarketing); headSales.add(salesExecutive1); headSales.add(salesExecutive2); headMarketing.add(clerk1); headMarketing.add(clerk2); //print all employees of the organization System.out.println(CEO); for (Employee headEmployee : CEO.getSubordinates()) { System.out.println(headEmployee); for (Employee employee : headEmployee.getSubordinates()) { System.out.println(employee); } } } } Bước 3 Xác minh kết quả đầu ra. Employee :[ Name : John, dept : CEO, salary :30000 ] Employee :[ Name : Robert, dept : Head Sales, salary :20000 ] Employee :[ Name : Richard, dept : Sales, salary :10000 ] Employee :[ Name : Rob, dept : Sales, salary :10000 ] Employee :[ Name : Michel, dept : Head Marketing, salary :20000 ] Employee :[ Name : Laura, dept : Marketing, salary :10000 ] Employee :[ Name : Bob, dept : Marketing, salary :10000 ] 10. Decorator Pattern Use case:
  37. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Code: Bước 1 Tạo giao diện. Shape.java public interface Shape { void draw(); } Bước 2 Tạo các lớp cụ thể triển khai cùng một giao diện. Rectangle.java public class Rectangle implements Shape { @Override public void draw() { System.out.println("Shape: Rectangle"); } }
  38. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Circle.java public class Circle implements Shape { @Override public void draw() { System.out.println("Shape: Circle"); } } Bước 3 Tạo lớp trang trí trừu tượng triển khai giao diện Shape . ShapeDecorator.java public abstract class ShapeDecorator implements Shape { protected Shape decoratedShape; public ShapeDecorator(Shape decoratedShape){ this.decoratedShape = decoratedShape; } public void draw(){ decoratedShape.draw(); } } Bước 4 Tạo lớp trang trí bê tông mở rộng lớp ShapeDecorator . RedShapeDecorator.java public class RedShapeDecorator extends ShapeDecorator { public RedShapeDecorator(Shape decoratedShape) { super(decoratedShape); } @Override public void draw() { decoratedShape.draw(); setRedBorder(decoratedShape); } private void setRedBorder(Shape decoratedShape){ System.out.println("Border Color: Red"); }
  39. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } Bước 5 Sử dụng RedShapeDecorator để trang trí các đối tượng Shape . DecoratorPatternDemo.java public class DecoratorPatternDemo { public static void main(String[] args) { Shape circle = new Circle(); Shape redCircle = new RedShapeDecorator(new Circle()); Shape redRectangle = new RedShapeDecorator(new Rectangle()); System.out.println("Circle with normal border"); circle.draw(); System.out.println("\nCircle of red border"); redCircle.draw(); System.out.println("\nRectangle of red border"); redRectangle.draw(); } } Bước 6 Xác minh kết quả đầu ra. Circle with normal border Shape: Circle Circle of red border Shape: Circle Border Color: Red Rectangle of red border Shape: Rectangle Border Color: Red 11. Facade Pattern: UML:
  40. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Các thành phần cơ bản của một Facade Pattern: Facade: biết rõ lớp của hệ thống con nào đảm nhận việc đáp ứng yêu cầu của client, sẽ chuyển yêu cầu của client đến các đối tượng của hệ thống con tương ứng. Subsystems: cài đặt các chức năng của hệ thống con, xử lý công việc được gọi bởi Facade. Các lớp này không cần biết Facade và không tham chiếu đến nó. Client: đối tượng sử dụng Facade để tương tác với các subsystem. Code: Bước 1 Tạo giao diện. Shape.java public interface Shape { void draw(); } Bước 2 Tạo các lớp cụ thể triển khai cùng một giao diện. Rectangle.java
  41. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public class Rectangle implements Shape { @Override public void draw() { System.out.println("Rectangle::draw()"); } } Square.java public class Square implements Shape { @Override public void draw() { System.out.println("Square::draw()"); } } Circle.java public class Circle implements Shape { @Override public void draw() { System.out.println("Circle::draw()"); } } Bước 3 Tạo lớp mặt tiền. ShapeMaker.java public class ShapeMaker { private Shape circle; private Shape rectangle; private Shape square; public ShapeMaker() { circle = new Circle(); rectangle = new Rectangle(); square = new Square(); } public void drawCircle(){ circle.draw(); } public void drawRectangle(){ rectangle.draw();
  42. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } public void drawSquare(){ square.draw(); } } Bước 4 Sử dụng mặt tiền để vẽ các loại hình dạng khác nhau. FacadePatternDemo.java public class FacadePatternDemo { public static void main(String[] args) { ShapeMaker shapeMaker = new ShapeMaker(); shapeMaker.drawCircle(); shapeMaker.drawRectangle(); shapeMaker.drawSquare(); } } Bước 5 Xác minh kết quả đầu ra. Circle::draw() Rectangle::draw() Square::draw() 12. Chain of Responsibility Pattern: UML:
  43. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Code: Bước 1 Tạo một lớp trình ghi tóm tắt. AbstractLogger.java public abstract class AbstractLogger { public static int INFO = 1; public static int DEBUG = 2; public static int ERROR = 3; protected int level; //next element in chain or responsibility protected AbstractLogger nextLogger; public void setNextLogger(AbstractLogger nextLogger){ this.nextLogger = nextLogger; } public void logMessage(int level, String message){ if(this.level <= level){ write(message);
  44. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } if(nextLogger !=null){ nextLogger.logMessage(level, message); } } abstract protected void write(String message); } Bước 2 Tạo các lớp cụ thể mở rộng bộ ghi nhật ký. ConsoleLogger.java public class ConsoleLogger extends AbstractLogger { public ConsoleLogger(int level){ this.level = level; } @Override protected void write(String message) { System.out.println("Standard Console::Logger: " + message); } } ErrorLogger.java public class ErrorLogger extends AbstractLogger { public ErrorLogger(int level){ this.level = level; } @Override protected void write(String message) { System.out.println("Error Console::Logger: " + message); } } FileLogger.java public class FileLogger extends AbstractLogger { public FileLogger(int level){ this.level = level; }
  45. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT @Override protected void write(String message) { System.out.println("File::Logger: " + message); } } Bước 3 Tạo các loại trình ghi nhật ký khác nhau. Gán chúng mức độ lỗi và đặt trình ghi tiếp theo trong mỗi trình ghi. Trình ghi tiếp theo trong mỗi trình ghi đại diện cho một phần của chuỗi. ChainPatternDemo.java public class ChainPatternDemo { private static AbstractLogger getChainOfLoggers(){ AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR); AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG); AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO); errorLogger.setNextLogger(fileLogger); fileLogger.setNextLogger(consoleLogger); return errorLogger; } public static void main(String[] args) { AbstractLogger loggerChain = getChainOfLoggers(); loggerChain.logMessage(AbstractLogger.INFO, "This is an information."); loggerChain.logMessage(AbstractLogger.DEBUG, "This is an debug level information."); loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information."); } } Bước 4 Xác minh kết quả đầu ra.
  46. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Standard Console::Logger: This is an information. File::Logger: This is an debug level information. Standard Console::Logger: This is an debug level information. Error Console::Logger: This is an error information. File::Logger: This is an error information. Standard Console::Logger: This is an error information. 13. Command Pattern: UML: Code: Account : là một request class. Command : là một interface của Command Pattern, cung cấp phương thức execute(). OpenAccount, CloseAccount : là các ConcreteCommand, cài đặt các phương thức của Command, sẽ thực hiện các xử lý thực tế. BankApp : là một class, hoạt động như Invoker, gọi execute() của ConcreteCommand để thực thi request. Client : tiếp nhận request từ phía người dùng, đóng gói request thành ConcreteCommand thích hợp và gọi thực thi các Command.
  47. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Bước 1 Tạo giao diện lệnh. Order.java public interface Order { void execute(); } Bước 2 Tạo một lớp yêu cầu. Stock.java public class Stock { private String name = "ABC"; private int quantity = 10; public void buy(){ System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] bought"); } public void sell(){ System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] sold"); } } Bước 3 Tạo các lớp cụ thể thực hiện giao diện Order . BuyStock.java public class BuyStock implements Order { private Stock abcStock; public BuyStock(Stock abcStock){ this.abcStock = abcStock; } public void execute() { abcStock.buy(); } }
  48. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT SellStock.java public class SellStock implements Order { private Stock abcStock; public SellStock(Stock abcStock){ this.abcStock = abcStock; } public void execute() { abcStock.sell(); } } Bước 4 Tạo lớp invoker lệnh. Broker.java import java.util.ArrayList; import java.util.List; public class Broker { private List orderList = new ArrayList (); public void takeOrder(Order order){ orderList.add(order); } public void placeOrders(){ for (Order order : orderList) { order.execute(); } orderList.clear(); } } Bước 5 Sử dụng lớp Broker để nhận và thực hiện các lệnh. CommandPatternDemo.java public class CommandPatternDemo { public static void main(String[] args) { Stock abcStock = new Stock();
  49. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT BuyStock buyStockOrder = new BuyStock(abcStock); SellStock sellStockOrder = new SellStock(abcStock); Broker broker = new Broker(); broker.takeOrder(buyStockOrder); broker.takeOrder(sellStockOrder); broker.placeOrders(); } } Bước 6 Xác minh kết quả đầu ra. Stock [ Name: ABC, Quantity: 10 ] bought Stock [ Name: ABC, Quantity: 10 ] sold 14. Iterator Pattern Aggregate : là một interface định nghĩa định nghĩa các phương thức để tạo Iterator object. ConcreteAggregate : cài đặt các phương thức của Aggregate, nó cài đặt interface tạo Iterator để trả về một thể hiện của ConcreteIterator thích hợp. Iterator : là một interface hay abstract class, định nghĩa các phương thức để truy cập và duyệt qua các phần tử. ConcreteIterator : cài đặt các phương thức của Iterator, giữ index khi duyệt qua các phần tử. Client : đối tượng sử dụng Iterator Pattern, nó yêu cầu một iterator từ một đối tượng collection để duyệt qua các phần tử mà nó giữ. Các phương thức của iterator được sử dụng để truy xuất các phần tử từ collection theo một trình tự thích hợp. Use case:
  50. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Code: Bước 1 Tạo giao diện. Iterator.java public interface Iterator { public boolean hasNext(); public Object next(); } Container.java public interface Container { public Iterator getIterator(); } Bước 2 Tạo lớp cụ thể thực hiện giao diện Container . Lớp này có NameIterator lớp bên trong thực hiện giao diện Iterator . NameRepository.java public class NameRepository implements Container { public String names[] = {"Robert" , "John" ,"Julie" , "Lora"}; @Override public Iterator getIterator() { return new NameIterator();
  51. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT } private class NameIterator implements Iterator { int index; @Override public boolean hasNext() { if(index < names.length){ return true; } return false; } @Override public Object next() { if(this.hasNext()){ return names[index++]; } return null; } } } Bước 3 Sử dụng NameRepository để lấy tên trình lặp và in. IteratorPatternDemo.java public class IteratorPatternDemo { public static void main(String[] args) { NameRepository namesRepository = new NameRepository(); for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){ String name = (String)iter.next(); System.out.println("Name : " + name); } } } Bước 4 Xác minh kết quả đầu ra.
  52. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Name : Robert Name : John Name : Julie Name : Lora 15. Observer Pattern UML: Chương trình của chúng ta như sau: Subject : cung cấp các phương thức để thêm, loại bỏ, thông báo observer. AccountService : đóng vai trò là ConcreteSubject, sẽ thông báo tới tất cả các observers bất cứ khi nào có thao tác của người dùng liên quan đến đăng nhập, tài khoản hết hạn. Observer : định nghĩa một phương thức update() cho các đối tượng sẽ được subject thông báo đến khi có sự thay đổi trạng thái. Phương thức này chấp nhận đối số là SubjectState, cho phép các ConcreteObserver sử dụng dữ liệu của nó.
  53. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT Logger, Mailer và Protector là các ConcreteObserver. Sau khi nhận được thông báo rằng có thao tác với user và gọi tới phương thức update(), các ConcreteObserver sẽ sử dụng dữ liệu SubjectState để xử lý. Code: Bước 1 Tạo lớp Chủ đề. Subject.java import java.util.ArrayList; import java.util.List; public class Subject { private List observers = new ArrayList (); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } } Bước 2 Tạo lớp Observer. Observer.java public abstract class Observer { protected Subject subject;
  54. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT public abstract void update(); } Bước 3 Tạo các lớp quan sát cụ thể BinaryObserver.java public class BinaryObserver extends Observer{ public BinaryObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Binary String: " + Integer.toBinaryString( subject.getState() ) ); } } OctalObserver.java public class OctalObserver extends Observer{ public OctalObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() { System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); } } HexaObserver.java public class HexaObserver extends Observer{ public HexaObserver(Subject subject){ this.subject = subject; this.subject.attach(this); } @Override public void update() {
  55. Youtube.com/PoppinKhiem - Sân chơi giới trẻ PTIT System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); } } Bước 4 Sử dụng Chủ thể và các đối tượng quan sát cụ thể. ObserverPatternDemo.java public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new Subject(); new HexaObserver(subject); new OctalObserver(subject); new BinaryObserver(subject); System.out.println("First state change: 15"); subject.setState(15); System.out.println("Second state change: 10"); subject.setState(10); } } Bước 5 Xác minh kết quả đầu ra. First state change: 15 Hex String: F Octal String: 17 Binary String: 1111 Second state change: 10 Hex String: A Octal String: 12 Binary String: 1010