享元模式
定义:提供了减少对象数量从而改善应用所需对象结构的方式。运用共享技术有效地支持大量细粒度对象。
适用场景:常用于系统底层的开发,以便于解决系统性能问题。系统有大量相似的对象、需要缓冲池的场景。
优点:减少对象的创建,降低内存中对象数量,降低系统的内存,提高效率。
缺点:关注内/外部状态、关注线程安全问题。使系统、程序的逻辑复杂化。
理解:就是缓存重复利用的对象,多次使用的同一情况,用到的是同一个对象。
public class EmployeeFactory {
private static final Map<String,Employee> EMPLOYEE_MAP = new HashMap<String,Employee>();
public static Employee getManager(String department){
Manager manager = (Manager) EMPLOYEE_MAP.get(department);
if(manager == null){
manager = new Manager(department);
System.out.print("创建部门经理:"+department);
String reportContent = department+"部门汇报:此次报告的主要内容是......";
manager.setReportContent(reportContent);
System.out.println(" 创建报告:"+reportContent);
EMPLOYEE_MAP.put(department,manager);
}
return manager;
}
private static final String departments[] = {"RD","QA","PM","BD"};
public static void main(String[] args) {
for(int i=0; i<10; i++){
String department = departments[(int)(Math.random() * departments.length)];
Manager manager = (Manager) EmployeeFactory.getManager(department);
manager.report();
}
}
}
组合模式
定义:将对象组合成“部份-整体”的层次结构。使客户端对单个对象和组合对象保持一致的方式处理。
适用场景:处理一个树形结构时。希望客户端可以忽略组合对象与单个对象的差异时。
优点:清楚的定义分层次的复杂对象,表示对象的全部或部份层次。让呵护短忽略了层次差异,方便对整个层次结构进行控制。简化客户端代码,符合开闭原则。
缺点:限制类型时会较为复杂,使设计变得更加抽象。(模糊化课程和目录类)
/**
* 抽象父类
*/
public abstract class CatalogComponent {
public void add(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持添加操作");
}
public void remove(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持删除操作");
}
public String getName(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持获取名称操作");
}
public double getPrice(CatalogComponent catalogComponent){
throw new UnsupportedOperationException("不支持获取价格操作");
}
public void print(){
throw new UnsupportedOperationException("不支持打印操作");
}
}
/**
* 课程
*/
public class Course extends CatalogComponent {
private String name;
private double price;
public Course(String name, double price) {
this.name = name;
this.price = price;
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public double getPrice(CatalogComponent catalogComponent) {
return this.price;
}
@Override
public void print() {
System.out.println("Course Name:"+name+" Price:"+price);
}
}
/**
* 目录
*/
public class CourseCatalog extends CatalogComponent {
private List<CatalogComponent> items = new ArrayList<CatalogComponent>();
private String name;
private Integer level;
public CourseCatalog(String name,Integer level) {
this.name = name;
this.level = level;
}
@Override
public void add(CatalogComponent catalogComponent) {
items.add(catalogComponent);
}
@Override
public String getName(CatalogComponent catalogComponent) {
return this.name;
}
@Override
public void remove(CatalogComponent catalogComponent) {
items.remove(catalogComponent);
}
@Override
public void print() {
System.out.println(this.name);
for(CatalogComponent catalogComponent : items){
if(this.level != null){
for(int i = 0; i < this.level; i++){
System.out.print(" ");
}
}
catalogComponent.print();
}
}
}
public static void main(String[] args) {
CatalogComponent linuxCourse = new Course("Linux课程",11);
CatalogComponent windowsCourse = new Course("Windows课程",11);
CatalogComponent javaCourseCatalog = new CourseCatalog("Java课程目录",2);
CatalogComponent mmallCourse1 = new Course("Java电商一期",55);
CatalogComponent mmallCourse2 = new Course("Java电商二期",66);
CatalogComponent designPattern = new Course("Java设计模式",77);
javaCourseCatalog.add(mmallCourse1);
javaCourseCatalog.add(mmallCourse2);
javaCourseCatalog.add(designPattern);
CatalogComponent imoocMainCourseCatalog = new CourseCatalog("主目录",1);
imoocMainCourseCatalog.add(linuxCourse);
imoocMainCourseCatalog.add(windowsCourse);
imoocMainCourseCatalog.add(javaCourseCatalog);
imoocMainCourseCatalog.print();
}
桥接模式
定义:将抽象部份与它的具体实现部份分离,使他们都可以独立地变化。通过组合的方式建立两个类之间的联系,而不是继承。
适用场景:抽象和具体实现间更多灵活性,一个类可能存在多个独立的变化,每个变化都需要独立的扩展。不希望适用继承,或应为多层继承导致系统类的个数剧增。
优点:分离抽象部份及其具体实现部份,提高了系统的可扩展性,符合开闭原则,符合合成复用原则。
缺点:增加了系统的理解与设计难度,需要正确地识别出系统中两个独立的变化。
账户
public interface Account {
Account openAccount();
void showAccountType();
}
public class DepositAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打开定期账号");
return new DepositAccount();
}
@Override
public void showAccountType() {
System.out.println("这是一个定期账号");
}
}
public class SavingAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打开活期账号");
return new SavingAccount();
}
@Override
public void showAccountType() {
System.out.println("这是一个活期账号");
}
}
银行
public abstract class Bank {
protected Account account;
public Bank(Account account){
this.account = account;
}
abstract Account openAccount();
}
public class ABCBank extends Bank {
public ABCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.println("打开中国农业银行账号");
account.openAccount();
return account;
}
}
public class ICBCBank extends Bank {
public ICBCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.println("打开中国工商银行账号");
account.openAccount();
return account;
}
}
public static void main(String[] args) {
Bank icbcBank = new ICBCBank(new DepositAccount());
Account icbcAccount = icbcBank.openAccount();
icbcAccount.showAccountType();
Bank icbcBank2 = new ICBCBank(new SavingAccount());
Account icbcAccount2 = icbcBank2.openAccount();
icbcAccount2.showAccountType();
Bank abcBank = new ABCBank(new SavingAccount());
Account abcAccount = abcBank.openAccount();
abcAccount.showAccountType();
}