-
Đỗ Lê Mạnh Hùng - 20020322
-
Đỗ Huy Anh - 20020180
- Design Pattern là một kỹ thuật trong lập trình hướng đối tượng, được sử dụng thường xuyên trong các ngôn ngữ hướng đối tượng. Design Pattern cung cấp các "mẫu thiết kế" và giải pháp để giải quyết các vấn đề chung thường gặp trong lập trình một cách tối ưu nhất.
1. Creational Pattern (Nhóm khởi tạo) gồm 5 mẫu:
- Factory Method
- Abstract Factory
- Builder
- Prototype
- Singleton
2. Structural Pattern (nhóm cấu trúc) gồm 7 mẫu:
- Adapter
- Bridge
- Composite
- Decorator
- Facade
- Flyweight
- Proxy
3. Behavioral Pattern (nhóm tương tác/ hành vi) gồm 11 mẫu:
- Interpreter
- Template Method
- Chain of Responsibility
- Command
- Iterator
- Mediator
- Memento
- Observer
- State
- Strategy
- Visitor
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Factory Method dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.factory.method;
/**
* 食物类型
*/
public enum FoodType {
HOT("热的"), COLD("凉的");
private String name;
FoodType(String foodType) {
this.name = foodType;
}
public String getName() {
return name;
}
}
- Mô hình các loại thức ăn.
- Super Class đã được cài đặt chính xác.
- Sub Class đã được cài đặt chính xác.
- Factory Class đã được cài đặt chính xác.
- Từ đoạn mã nguồn trên, ta thấy có biến foodType, biến này tương ứng với TPBank hoặc VietComBank, vì vậy trong Enum Foodtype khác với mẫu chuẩn 1 biến khai báo enum.
- Các thành phần cấu trúc còn lại giống nhau.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Abstract Factory dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
public class YoungTeamFactory implements TeamFactory {
public Ship createShip() {
return new NewShip();
}
public Captain createCaptain() {
return new YoungCaptain();
}
public Sailor createSailor() {
return new YoungSailor();
}
}
- AbstractProduct được khai báo chính xác.
- Product đã được cài đặt chính xác.
- AbstractFactory được khai báo chính xác.
- ConcreteFactory có được xây dựng nhưng các biến không được khai báo dưới dạng public.
public interface TeamFactory {
Ship createShip();
Captain createCaptain();
Sailor createSailor();
}
- Lớp YoungTeamFactory trong mã nguồn tương ứng với 1 trong 4 lớp sau: Plastic Chair, Plastic Table, Wood Chair, Wood Table.
- Qua đoạn mã nguồn trên ta thấy là ngoài lớp dạng ConcreteFactory thì các lớp còn lại đều giống với dạng cấu trúc chuẩn.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Builder dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
public class Person {
private final String name;
private final Integer age;
private final Nationality nationality;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Nationality getNationality() {
return nationality;
}
public SkinColor getSkinColor() {
return skinColor;
}
private final SkinColor skinColor;
public Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.skinColor = builder.skinColor;
this.nationality = builder.nationality;
}
}
- ConcreteBuilder chưa kế thừa Builder
public static class Builder {
private String name;
private Integer age;
private Nationality nationality;
private SkinColor skinColor;
public Builder age(Integer age) {
this.age = age;
return this;
}
public Builder name(String name) {
if (null == name) {
throw new IllegalArgumentException("人必须有名字!");
}
this.name = name;
return this;
}
public Builder nationality(Nationality nationality) {
this.nationality = nationality;
return this;
}
public Builder skinColor(SkinColor skinColor) {
this.skinColor = skinColor;
return this;
}
public Person build() {
return new Person(this);
}
}
- Director đã được cài đặt chính xác
- Product đã được cài đặt chính xác
- Builder chưa phải là abstract class hay interface
public class Person {
private final String name;
private final Integer age;
private final Nationality nationality;
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Nationality getNationality() {
return nationality;
}
public SkinColor getSkinColor() {
return skinColor;
}
private final SkinColor skinColor;
public Person(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.skinColor = builder.skinColor;
this.nationality = builder.nationality;
}
}
- Qua đây ta thấy trong dạng cấu trúc builder, các lớp Builder và ConcreteBuilder tương ứng trong mã nguồn chưa được cài đặt chính xác như mẫu chuẩn đã được cho ở trên, các thành phần còn lại thì đã chính xác.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Prototype dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.prototype;
/**
* 乘客
*/
public abstract class Passenger extends Prototype {
@Override
protected abstract Passenger clone() throws CloneNotSupportedException;
}
- Hàm abstract giống hệt mẫu chuẩn.
- Prototype đã được cài đặt chính xác
- ConcretePrototype đã dược cài đặt chính xác
- Client đã được cài đặt
- Qua đây ta thấy được cấu trúc ở mã nguồn đã giống với cấu trúc ở trong mẫu chuẩn đã được cho ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Singleton dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
- Đã có một method public static được cài đặt
- Private Contructor đã được cài đặt
- Chưa cài đặt biến ở dưới dạng private static final
private static Singleton instance;
private Singleton() {}
- Qua đây ta thấy ngoài việc biến chưa được cài đặt dưới dạng chuẩn thì phần còn lại của cấu trúc trong mã nguồn đã giống với cấu trúc mẫu chuẩn được cho ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Adapter dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.adapter;
/**
* 公共汽车适配器
*/
public class BusAdapter implements Car {
private Bus bus;
public BusAdapter() {
this.bus = new Bus();
}
@Override
public void drive() {
bus.run();
}
}
- Một ví dụ về mô hình xe Bus trong class Car.
- Adaptee đã được khai báo chính xác
- Adapter được khai báo chính xác
- Target được khai báo chính xác
- Qua đây ta thấy được cấu trúc đã được cho ở trong mã nguồn đã chính xác khi so sánh với cấu trúc ở trong mẫu thiết kế chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Bridge dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
public interface War {
Enemy getEnemy();
void startWar();
void combatting();
void stopWar();
}
package me.zbl.bridge;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 强大的敌人
*/
public class IntrepidEnemy implements Enemy {
private static final Logger LOGGER = LoggerFactory.getLogger(IntrepidEnemy.class);
@Override
public void onStartWar() {
LOGGER.info("敌人信心满满,准备迎战");
}
@Override
public void onCombatting() {
LOGGER.info("敌人正在积极反抗");
}
@Override
public void onStopWar() {
LOGGER.info("双方达成了平手");
}
}
- Refined Abstraction được cài đặt chính xác
- Implementor được khai báo chính xác
- ConcreteImplementor được khai báo chính xác
- Abstraction được cài đặt dưới dạng interface thay vì là class abstraction
public interface War {
Enemy getEnemy();
void startWar();
void combatting();
void stopWar();
}
- Qua đây ta thấy được class Abstraction tương ứng ở trong mã nguồn chưa đúng với cấu trúc mẫu chuẩn đã được cho ở trên. Phần còn lại của chương trình đã được cài đặt chính xác.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Composite dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.composite;
import java.util.ArrayList;
import java.util.List;
/**
* 字母组合的抽象类
*/
public abstract class CharacterComposite {
private List<CharacterComposite> children = new ArrayList<>();
public void add(CharacterComposite character) {
children.add(character);
}
public int count() {
return this.children.size();
}
public void printBefore() {
}
public void printAfter() {
}
public void print() {
printBefore();
for (CharacterComposite item : children) {
item.print();
}
printAfter();
}
}
- Thêm các thứ tiếng, giống y hệt mẫu chuẩn.
- Base Component đã được khai báo chính xác
- Leaf đã được cài đặt chính xác
- Composite đã được cài đặt chính xác
- Qua đây ta thấy được cấu trúc trong mã nguồn đã chính xác so với cấu trúc ở trong mẫu chuẩn.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Decorator dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.decorator;
/**
* 流水线上操作行为的接口
*/
public interface Operation {
void checkBefore();
void join();
void chekcAfter();
}
- Hàm Interface Operation có các hàm bên trong giống theo cấu trúc mẫu chuẩn.
- Component đã được cài đặt đúng
- ConcreteComponent đã được cài đặt chính xác
- Decorator đã được cài đặt chính xác
- ConcreteDecorator đã được cài đặt chính xác
- Qua đây ta thấy được cấu trúc trong mã nguồn đã chính xác so với cấu trúc ở trong mẫu chuẩn.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Facade dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.facade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class CourseParticipator {
private static final Logger LOGGER = LoggerFactory.getLogger(CourseParticipator.class);
public void prepareCourse() {
LOGGER.info("{}准备上课", name());
}
public void proceedCourse() {
LOGGER.info("{}正在上课", name());
}
public void stopCourse() {
LOGGER.info("{}下课", name());
}
public void goToSchool() {
LOGGER.info("{}赶往学校", name());
}
public void goHome() {
LOGGER.info("{}回家", name());
}
public abstract String name();
public void action(Event... events) {
for (Event e : events) {
action(e);
}
}
private void action(Event e) {
switch (e) {
case EVENT_PREPARE: {
prepareCourse();
break;
}
case EVENT_PROCEED: {
proceedCourse();
break;
}
case EVENT_STOP: {
stopCourse();
break;
}
case EVENT_GO_HOME: {
goHome();
break;
}
case EVENT_GOTO_SCHOOL: {
goToSchool();
break;
}
default: {
LOGGER.info("未知操作");
break;
}
}
}
static enum Event {
EVENT_GOTO_SCHOOL, EVENT_PREPARE, EVENT_PROCEED, EVENT_STOP, EVENT_GO_HOME;
}
}
- Hàm abstract có các lớp con là student và teacher.
- Có đầy đủ các cấu trúc giống như định dạng chuẩn.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Flyweight dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.flyweight;
import java.util.EnumMap;
import java.util.Map;
import static me.zbl.flyweight.GunType.*;
/**
* 武器工厂
*/
public class GunFactory {
private Map<GunType, Shooting> gunRepo;
public GunFactory() {
gunRepo = new EnumMap<GunType, Shooting>(GunType.class);
}
public Shooting createGun(GunType type) {
Shooting gun = gunRepo.get(type);
if (null == gun) {
switch (type) {
case HANDGUN: {
gun = new HandGun();
gunRepo.put(HANDGUN, gun);
break;
}
case MUSKET: {
gun = new Musket();
gunRepo.put(MUSKET, gun);
break;
}
case SNIPER: {
gun = new Sniper();
gunRepo.put(SNIPER, gun);
break;
}
case SUBMACHINE: {
gun = new Submachine();
gunRepo.put(SUBMACHINE, gun);
break;
}
}
}
return gun;
}
}
- Code về các loại súng.
- Flyweight đã được cài đặt chính xác
- ConcreteFlyweight đã được cài đặt chính xác
- UnsharedFlyweight đã được cài đặt chính xác
- FlyweightFactory đã được cài đặt chính xác
- Client đã được cài đặt
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Proxy dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.proxy;
public interface Room {
void enter(Customer customer);
}
- Interface Room có hàm "void enter" giống như mẫu chuẩn thiết kế proxy.
- Giống cấu trúc gốc 100%.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Interpreter dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.interpreter;
/**
* 减法表达式
*/
public class MinusExpression extends Expression {
private Expression expressionLeft;
private Expression expressionRight;
public MinusExpression(Expression expressionLeft, Expression expressionRight) {
this.expressionLeft = expressionLeft;
this.expressionRight = expressionRight;
}
@Override
public int interpret() throws Exception {
return expressionLeft.interpret() - expressionRight.interpret();
}
@Override
public String toString() {
return "-";
}
}
- Theo mẫu chuẩn, ta thấy được có lớp MinusEx đã kế thừa lớp Expression.
- Mẫu thiết kế giống 90%, thiếu mất cấu trúc context.
- Qua đây ta thấy được đa phần cấu trúc trong mã nguồn đã giống với mẫu thiết kế, tuy vậy vẫn thiếu thành phần context để cho người dùng biết được đây là một ứng dụng máy tính bỏ túi
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Factory Method dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.template.method;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Template method
*/
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
Student student = new Student(new PositiveLearningMethod());
student.learn("上课走神", "同学");
LOGGER.info("更换学习方法");
student.changeMethod(new NegativeLearinngMethod());
student.learn("认证听讲", "老师");
}
}
- Hàm tượng trưng client trong mẫu chuẩn.
- Có đầy đủ cấu trúc Abstract Class và 1 concrete Class ngoài ra thêm 1 phương thức của Abstract class và 1 hàm nữa.
- Qua đây ta có thể thấy được cấu trúc trong mã nguồn đã được cài đặt chính xác, ngoài ra còn được cài đặt thêm một vài phương thức và hàm khác để cho cấu trúc có độ hoàn chỉnh cao hơn.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Chain of Responsibility dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.chain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
private RequestHandler next;
public RequestHandler(RequestHandler next) {
this.next = next;
}
public void handleRequest(Request request) {
if (null != next) {
next.handleRequest(request);
}
}
@Override
public abstract String toString();
protected void printHandleMessage(Request request) {
LOGGER.info("{}处理消息中,消息内容为:{}", this, request);
}
}
- Hàm abstract giống như mẫu chuẩn.
- Mẫu thiết kế theo repo có cấu trúc giống 90% theo mẫu chuẩn, chỉ khác có thêm 2 lớp để khai báo.
- Đã cài đặt được lớp Request tương đương với lớp Client ở trong mẫu chuẩn.
- Qua đây ta thấy ngoài việc cấu trúc mã nguồn đã giống với cấu trúc mẫu chuẩn, đã có 2 lớp thêm được cài đặt để làm cấu trúc mã nguồn đa dạng hơn.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Command dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.command;
/**
* 命令抽象类
*/
public abstract class Command {
public abstract void execute();
public abstract void undo();
public abstract void redo();
@Override
public abstract String toString();
}
- Hầm abstract có các hàm hỗ trợ cho lớp Command, giống như mẫu chuẩn.
- Mẫu thiết kế theo repo có đủ cấu trúc, đó là interface or abstract class, có implemention, có tiếp nhận request, tiếp nhật concrete và nơi nhận( giống 100%).
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Iterator dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
public class Item {
private ItemType type;
private String name;
public Item(ItemType type, String name) {
this.type = type;
this.name = name;
}
public final void setType(ItemType type) {
this.type = type;
}
public ItemType getType() {
return type;
}
@Override
public String toString() {
return name;
}
}
- Class Item gồm các item con bên trong, là lớp cha của các items đó.
- Mẫu thiết kế giống 100%.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Mediator dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.mediator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class AbstractPartyMember implements PartyMember {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPartyMember.class);
private Party party;
@Override
public void joinParty(Party party) {
LOGGER.info("{}加入了派对", this);
this.party = party;
}
@Override
public void act(Activity activity) {
if (null != activity) {
LOGGER.info("{}提议进行{}活动", this, activity);
party.letAct(this, activity);
}
}
@Override
public void partyActivity(Activity activity) {
LOGGER.info("进行派对活动,名称:{},介绍:{}", activity, activity.getDescription());
}
@Override
public abstract String toString();
}
- Class abtract khai báo các biến và hàm con, giống lớp chuẩn.
- Có đầy đủ cấu trúc giống form chuẩn, và thêm 1 biến enum.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Memento dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.memento;
/**
* 植物接口
*/
public interface Plant {
int getWeight();
int getHeight();
FlowerType getType();
}
- Lớp interface Plant giống lớp Interface của mẫu chuẩn thiết kế.
- Mẫu thiết kế theo repo đầy đủ cấu trúc originator, caretaker và memento trong đó có thêm 1 loại biến enum.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Observer dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.observer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Southern implements TimeObserver {
private static final Logger LOGGER = LoggerFactory.getLogger(Southern.class);
@Override
public void update(TimePoint time) {
LOGGER.info("南方人吃饭了");
switch (time) {
case MORNING:
LOGGER.info("热干面");
break;
case NOON:
LOGGER.info("米饭");
break;
case AFTERNOON:
LOGGER.info("茶");
break;
case EVENING:
LOGGER.info("鱼");
break;
default:
break;
}
}
}
- Hàm Southern kế thừa TimeObserver như mẫu chuẩn.
- Có đầy đủ các trúc như subject, observer, concreteSubject và concreteObserver, và thêm 1 biến enum.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu State dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.state;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IdleState implements State {
private static final Logger LOGGER = LoggerFactory.getLogger(IdleState.class);
private Coder coder;
public IdleState(Coder coder) {
this.coder = coder;
}
@Override
public void onPreparing() {
LOGGER.info("{}正努力使自己变得平静", coder);
}
@Override
public void onEnterState() {
LOGGER.info("{}正悠闲的听着歌", coder);
}
}
- Lớp con IdleState kế thừa lớp cha State theo cấu trúc mẫu chuẩn State.
- Có đầy đủ các cấu trúc context, state và concreteState và có thêm hàm main.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên, ngoài ra còn có thêm hàm main để có thể thực thi chương trình.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Strategy dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.strategy;
public class BusinessMan {
private TransportationStrategy strategy;
public BusinessMan(TransportationStrategy strategy) {
this.strategy = strategy;
}
public void changetStrategy(TransportationStrategy strategy) {
this.strategy = strategy;
}
public void transport() {
this.strategy.go();
}
}
- Mô hình BusinessMan đầy đủ các biến như trên.
- Có đầy đủ các cấu trúc như strategy, 2 concreteStrategy, context và 1 hàm main.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.
Bên dưới là đoạn mã nguồn được sử dụng trong mẫu Visitor dùng để so sánh với mẫu chuẩn được minh họa bằng hình ảnh dưới đây:
package me.zbl.visitor;
public abstract class Unit {
private Unit[] children;
public Unit(Unit... children) {
this.children = children;
}
/**
* 接受访问
*/
public void beVisited(UnitVisitor visitor) {
for (Unit childUnit : children) {
childUnit.beVisited(visitor);
}
}
}
- Nhìn vào dòng code cho thấy các desgin pattern đã được chuẩn bị giống 90%.
- Có đầy đủ các file trong cấu trúc như visitor, concreteVisitor, element và phương thức của elements, objectStructure và client, và 1 hàm để chạy.
- Qua đây ta thấy cấu trúc ở trong mã nguồn đã đạt được độ chính xác tương đương với cấu trúc ở trong mẫu chuẩn ở trên.