Một diểm đặc biệt cần chú ý là pattern này được thực hiện trong môi trường đa luồng để multible phải truy cậpvào các nguồn tài nguyên của cùng các đối tượng singleton.. Tình huống sử dụn
Trang 1HỌC VIÊN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG
Trang 2I.Creational Design Patterns:
1. Singleton
Ý Nghĩa : “Đảm bảo rằng một lớp chỉ có duy nhất một thể hiện và cung cấp một biến toàn cục đểtruy cập nó”Singleton pattern được sử dụng khi chúng ta phải đảm bảo rằng chỉ có một thể hiện của một lớp được tạo ra và các thể hiện phải có sẵn và thông qua tất cả các mã Một diểm đặc biệt cần chú ý là pattern này được thực hiện trong môi trường đa luồng để multible phải truy cậpvào các nguồn tài nguyên của cùng các đối tượng singleton
Tình huống sử dụng :
- Các lớp Logger
- Các lớp Configuration
- Chế độ chia sẻ tài nguyên
Sử dụng mẫu Singleton khi bạn muốn hạn chế việc sử dụng tài nguyên (thay vì việc tạo không hạn chế số lượng đối tượng) hoặc khi bạn cần phải xử lý một đối tượng nhạy cảm, mà dữ liệu của nó không thể chia sẻ cho mọi thể hiện, như registry của Windows
Mẫu thiết kế :
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
Trang 3//instantiated
private SingleObject(){}
//Get the only object available
public static SingleObject getInstance(){
return instance;
}
public void showMessage(){
System.out.println("Hello World!");
}
}
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();
}
}
Kết quả chạy:
Trang 4public 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
Trang 5public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method."); }
}
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();
} else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square();
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");
Trang 6//call draw method of circle
Tình huống sử dụng :
Trang 7Định nghĩa một giao diện cho việc tạo ra các đối tượng, nhưng hãy để lớp con để quyết định lớp
để khởi tạo
Đề cập đến các đối tượng mới được tạo ra thông qua một giao diện phổ biến
Mẫu thiết kế :
4.Abstract Factory
Ý nghĩa : Một hệ thống phải được cấu hình với một trong nhiều sản phẩm của hệ thống
Một hệ thống nên được độc lập với sản phẩm của mình được tạo ra, sáng tác và đại diện
Các sản phẩm từ cùng một hệ thống nên được sử dụng tất cả cùng nhau, các sản phẩm từ các hệ thống khác nhau không được sử dụng cùng nhau và hạn chế này phải được đảm bảo
Chỉ các giao diện sản phẩm được tiết lộ, việc triển khai vẫn còn ẩn cho khách hàng
Tình huống sử dụng :
java.awt.Toolkit - lớp cha trừu tượng của tất cả các triển khai thực tế của Abstract Window Toolkit Lớp con của Bộ công cụ được sử dụng để ràng buộc các thành phần khác nhau để cụ thểtriển khai bộ công cụ bản địa (Java AWT)
javax.swing.LookAndFeel - một Abstract Factory swing để swithct giữa một số giao diện cho các thành phần hiển thị (Java Swing)
java.sql.Connection - một Abstract Factory swing mà tạo báo cáo, PreparedStatements,
CallableStatements, cho mỗi đơn vị cơ sở dữ liệu
Mẫu thiết kế :
Trang 8public 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.");
Trang 9public void draw() {
System.out.println("Inside Circle::draw() method."); }
public void fill() {
System.out.println("Inside Red::fill() method."); }
}
Green.java
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method."); }
}
Blue.java
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method."); }
}
AbstractFactory.java
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape)
Trang 10return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){ return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){ return new Square();
return new Red();
} else if(color.equalsIgnoreCase("GREEN")){
return new Green();
} else if(color.equalsIgnoreCase("BLUE")){
return new Blue();
Trang 11public class FactoryProducer {
public static AbstractFactory getFactory(String choice){
if(choice.equalsIgnoreCase("SHAPE")){
return new ShapeFactory();
} else if(choice.equalsIgnoreCase("COLOR")){
return new ColorFactory();
public class AbstractFactoryPatternDemo {
public static void main(String[] args) {
//get shape factory
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE"); //get an object of Shape Circle
Shape shape1 = shapeFactory.getShape("CIRCLE");
//call draw method of Shape Circle
shape1.draw();
//get an object of Shape Rectangle
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//call draw method of Shape Rectangle
shape2.draw();
//get an object of Shape Square
Shape shape3 = shapeFactory.getShape("SQUARE");
//call draw method of Shape Square
shape3.draw();
//get color factory
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR"); //get an object of Color Red
Color color1 = colorFactory.getColor("RED");
Trang 12//call fill method of Red
color1.fill();
//get an object of Color Green
Color color2 = colorFactory.getColor("Green"); //call fill method of Green
color2.fill();
//get an object of Color Blue
Color color3 = colorFactory.getColor("BLUE");
//call fill method of Color Blue
color3.fill();
}
}
Kết quả chạy:
Trang 13Ý nghĩa :
Tiết kiệm là một vấn đề lớn khi nói đến sử dụng tài nguyên máy tính, do đó các lập trình viên đang làm hết sức mình để tìm cách cải thiện hiệu suất Khi chúng ta nói về đối tượng sáng tạo, chúng tôi có thể tìm thấy một cách tốt hơn để có đối tượng mới: nhân bản Ý tưởng này một mẫu thiết kế đặc biệt là liên quan: thay vì tạo ra nó sử dụng nhân bản Nếu chi phí của việc tạo ra một đối tượng mới là lớn và sáng tạo là nguồn lực chuyên sâu, chúng ta sao chép các đối tượng
ó cho phép một đối tượng để tạo các đối tượng tùy chỉnh mà không biết lớp học của họ hay bất
kỳ chi tiết làm thế nào để tạo ra chúng Tính đến thời điểm này có vẻ rất giống mô hình Factory Method, sự khác biệt là thực tế là cho Factory của các đối tượng nguyên mẫu không bao giờ có.Tình huống sử dụng :
quy định cụ thể các loại của các đối tượng để tạo ra bằng cách sử dụng một ví dụ nguyên
mẫu ,tạo các đối tượng mới bằng cách sao chép nguyên mẫu này
Trang 14protected String type;
public Object clone() {
Object clone = null;
public void draw() {
System.out.println("Inside Rectangle::draw() method."); }
Trang 15public void draw() {
System.out.println("Inside Square::draw() method."); }
public void draw() {
System.out.println("Inside Circle::draw() method."); }
}
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();
Trang 16PrototypePatternDemo.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());
Trang 17bằng cách nhân bản các đối tượng, mô hình Object Pool cung cấp một cơ chế để tái sử dụng các đối tượng là đắt tiền để tạo
Khách hàng của một đối tượng kéo "cảm thấy" như họ là chủ sở hữu của một dịch vụ mặc dù cácdịch vụ được chia sẻ giữa nhiều khách hàng khác
Mô hình này cho phép một đối tượng khách hàng để xây dựng một đối tượng phức tạp bằng cáchxác định thể loại và nội dung của nó, đã bị che các chi tiết liên quan đến việc đại diện các đối tượng Bằng cách này, quá trình xây dựng có thể được sử dụng để tạo các biểu tượng khác nhau Logic của quá trình này là cô lập dưới hình thức các bước thực tế sử dụng trong việc tạo ra các đối tượng phức tạp, vì vậy quá trình có thể được sử dụng lại để tạo ra một đối tượng khác nhau hình thành cùng một tập hợp của các đối tượng đơn giản như là người đầu tiên
Tình huống sử dụng :
Trang 18Xác định một thể hiện cho việc tạo ra một đối tượng nhưng để cho lớp con quyết định lớp để khởi tạo
Đề cập đến các đối tượng mới được tạo ra thông qua một giao diện phổ biến
Trang 19dụ thông thường nhất của một máy bằng cách sử dụng Chain of Responsibiliy là bán hàng tự động khe cắm máy đồng xu : hơn là có một khe đối với từng loại đồng tiền , máy chỉ có một khe cắm cho tất cả chúng Các đồng tiền giảm được chuyển đến nơi lưu trữ thích hợp được xác định bởi người nhận lệnh
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;
Trang 20public void setNextLogger(AbstractLogger nextLogger){ this.nextLogger = nextLogger;
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){
Trang 21this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File::Logger: " + message);
}
}
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.");
}
}
Kêt quả chạy:
Trang 22Ý nghĩa :
Các mẫu thiết kế lệnh Command(các cuộc gọi phương pháp) trong các đối tượng cho phép chúngtôi phát hành yêu cầu mà không biết các hoạt động yêu cầu hoặc các đối tượng yêu cầu Mẫu thiết kế lệnh cung cấp các tùy chọn để xếp hàng lệnh, undo / redo hành động và thao tác khác.Tình huống sử dụng :
- Gói gọn một yêu cầu trong một đối tượng
- Cho phép các tham số của khách hàng với các yêu cầu khác nhau
- Cho phép tiết kiệm các yêu cầu trong một hàng đợi
Mẫu thiết kế :
Trang 23public 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");
Trang 24private Stock abcStock;
public BuyStock(Stock abcStock){
public class SellStock implements Order {
private Stock abcStock;
public SellStock(Stock abcStock){
import java.util.ArrayList;
import java.util.List;
public class Broker {
private List<Order> orderList = new ArrayList<Order>(); public void takeOrder(Order order){
orderList.add(order);
}
public void placeOrders(){
for (Order order : orderList) {
Trang 25public static void main(String[] args) {
Stock abcStock = new Stock();
BuyStock buyStockOrder = new BuyStock(abcStock);
SellStock sellStockOrder = new SellStock(abcStock);
Broker broker = new Broker();
Trang 26Tình huống sử dụng :
Mẫu thiết kế :
Expression.java
public interface Expression {
public boolean interpret(String context);
Trang 27public boolean interpret(String context) {
public class OrExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public OrExpression(Expression expr1,Expression expr2) { this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) || expr2.interpret(context); }
}
AndExpression.java
public class AndExpression implements Expression {
private Expression expr1 = null;
private Expression expr2 = null;
public AndExpression(Expression expr1,Expression expr2) { this.expr1 = expr1;
this.expr2 = expr2;
}
@Override
public boolean interpret(String context) {
return expr1.interpret(context) && expr2.interpret(context); }
}
InterpreterPatternDemo.java
public class InterpreterPatternDemo {
//Rule: Robert and John are male
public static Expression getMaleExpression(){
Expression robert = new TerminalExpression("Robert");
Trang 28Expression john = new TerminalExpression("John");
return new OrExpression(robert, john);
}
//Rule: Julie is a married women
public static Expression getMarriedWomanExpression(){
Expression julie = new TerminalExpression("Julie");
Expression married = new TerminalExpression("Married"); return new AndExpression(julie, married);
}
public static void main(String[] args) {
Expression isMale = getMaleExpression();
Expression isMarriedWoman = getMarriedWomanExpression(); System.out.println("John is male? " + isMale.interpret("John")); System.out.println("Julie is a married women? "
+ isMarriedWoman.interpret("Married Julie"));
Trang 29một cơ chế để tạo điều kiện cho sự tương tác giữa các đối tượng trong một cách thức đối tượng
mà không nhận thức được sự tồn tại của các đối tượng khác
Tình huống sử dụng :
Xác định một đối tượng mà gói gọn như thế nào một tập các đối tượng tương tác Hòa giải thúc đẩy khớp nối lỏng lẻo bằng cách giữ các đối tượng từ đề cập đến nhau một cách rõ ràng, và nó cho phép bạn thay đổi tương tác một cách độc lập
Mẫu thiết kế
ChatRoom.java
import java.util.Date;
public class ChatRoom {
public static void showMessage(User user,String message){
System.out.println(new Date().toString()
+ " [" + user.getName() +"] : " + message);
}
}
User.java
public class User {
private String name;
public String getName() {