Giáo trình Kiến trúc và thiết kế phần mềm

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:  
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  
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();  
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.  
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:  
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 {  
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();  
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.  
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  
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();  
}
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";  
}
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<Item> items = new ArrayList<Item>();  
public void addItem(Item item){  
items.add(item);  
}
public float getCost(){  
float cost = 0.0f;  
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 {  
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:  
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(){  
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";  
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<String, Shape> shapeMap = new  
Hashtable<String, Shape>();  
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);  
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  
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  
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 {  
Tải về để xem bản đầy đủ
pdf 55 trang yennguyen 09/04/2022 13140
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Kiến trúc và thiết kế phần mềm", để tải tài liệu gốc về máy hãy click vào nút Download ở trên

File đính kèm:

  • pdfgiao_trinh_kien_truc_va_thiet_ke_phan_mem.pdf