default
设计模式
Abstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
Adpater:将一个类的接口转换成客户希望的另外一个接口。 由于接口不兼容而不能一起工作的那些类可以一起工作。
Bridge:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
Builder:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
Chain of Responsibility:为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
Command:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
Compsite:将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e使得客户对单个对象和复合对象的使用具有一致性。
Decorator:动态地给一个对象添加一些额外的职责。就扩展功能而言,D e c o r a t o r模式比生成子类方式更为灵活。
Facade:为子系统中的一组接口提供一个一致的界面,F a c a d e模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
Factory Method:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。
FlyWeight:运用共享技术有效地支持大量细粒度的对象。
Interpreter:给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 器使用该表示来解释语言中的句子。
Iterator:提供一种方法顺序访问一个聚合对象中各个元素 内部表示。
Meditor:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
Memento:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
Observe:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
Prototype:用原型实例指定创建对象的种类,并且通过拷贝这个原型创建新的对象。
Proxy:为其他对象提供一个代理以控制对这个对象的访问。
Singleton:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
State:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
Strategy:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模
式使得算法的变化可独立于使用它的客户。
Template Method:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Visitor:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
设计模式简述
设计模式在粒度和抽象层次上各不相同,由于众多的设计模式,我们可以将他们组织起来。将设计模式进行分类可以方便我们进行引用。

我们根据两条准则进行分类:
- 创建型设计模式与对象的创建有关
- 结构型模式与类和对象的组合有关
- 行为型设计模式对类和对象怎样交互和怎样分配职责进行描述。
单例模式
举个例子:
有一个仓库
想要使用代码完成仓库的管理,简历仓库类和工人类
出现的问题:
通过测试发现,每次工人搬运操作都会新建一个仓库,就是货物都不是放在同一仓库,这是怎么回事呢?(看下面代码)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
class StoreHouse { private int quantity = 100;
public void setQuantity(int quantity) { this.quantity = quantity; }
public int getQuantity() { return quantity; } }
class Carrier{ public StoreHouse mStoreHouse; public Carrier(StoreHouse storeHouse){ mStoreHouse = storeHouse; } public void MoveIn(int i){ mStoreHouse.setQuantity(mStoreHouse.getQuantity()+i); } public void MoveOut(int i){ mStoreHouse.setQuantity(mStoreHouse.getQuantity()-i); } }
public class SinglePattern { public static void main(String[] args){ StoreHouse mStoreHouse1 = new StoreHouse(); StoreHouse mStoreHouse2 = new StoreHouse(); Carrier Carrier1 = new Carrier(mStoreHouse1); Carrier Carrier2 = new Carrier(mStoreHouse2);
System.out.println("两个是不是同一个?");
if(mStoreHouse1.equals(mStoreHouse2)){ System.out.println("是同一个"); }else { System.out.println("不是同一个"); } Carrier1.MoveIn(30); System.out.println("仓库商品余量:"+Carrier1.mStoreHouse.getQuantity()); Carrier2.MoveOut(50); System.out.println("仓库商品余量:"+Carrier2.mStoreHouse.getQuantity()); } }
|
实现一个类,只有一个实例化对象&只提供一个全局访问点
解决问题的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| class StoreHouse {
private int quantity = 100; private static StoreHouse ourInstance = new StoreHouse();; public static StoreHouse getInstance() { return ourInstance; }
private StoreHouse() { }
public void setQuantity(int quantity) { this.quantity = quantity; }
public int getQuantity() { return quantity; } }
class Carrier{ public StoreHouse mStoreHouse; public Carrier(StoreHouse storeHouse){ mStoreHouse = storeHouse; } public void MoveIn(int i){ mStoreHouse.setQuantity(mStoreHouse.getQuantity()+i); } public void MoveOut(int i){ mStoreHouse.setQuantity(mStoreHouse.getQuantity()-i); } }
public class SinglePattern { public static void main(String[] args){ StoreHouse mStoreHouse1 = StoreHouse.getInstance(); StoreHouse mStoreHouse2 = StoreHouse.getInstance(); Carrier Carrier1 = new Carrier(mStoreHouse1); Carrier Carrier2 = new Carrier(mStoreHouse2);
System.out.println("两个是不是同一个?");
if(mStoreHouse1.equals(mStoreHouse2)){ System.out.println("是同一个"); }else { System.out.println("不是同一个"); } Carrier1.MoveIn(30); System.out.println("仓库商品余量:"+Carrier1.mStoreHouse.getQuantity()); Carrier2.MoveOut(50); System.out.println("仓库商品余量:"+Carrier2.mStoreHouse.getQuantity()); } }
|
写两种多线程加高性能写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class SingleTon{ private static volatile SingleTon instance; private SingleTon(){} public SingleTon getInstance(){ if(instance == null){ synchronized(SingleTon.class){ if(instance == null){ instance = new SingleTon(); } } return instance; } } }
class SingleTon2{ private SingleTon2(){} private static class SingleTonHolder{ private static final SingleTon INSTANCE = new SingleTon(); } public static SingleTon getInstance(){ return SingleTon.INSTANCE; } }
|
策略模式
举个例子:
我有一个百货公司,最近准备促销活动,冲突
每个节日使用一个促销活动太枯燥,没有吸引力
第一步: 定义一个抽象策略角色:百货公司所有促销活动共同使用
1 2 3
| public abstract class Strategy{ public abstract void show(); }
|
第二部:定义具体策略角色,每个节日具体的促销活动
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class StrategyA extends Strategy{
@Override public void show() { System.out.println("为春节准备的促销活动A"); } }
class StrategyB extends Strategy{
@Override public void show() { System.out.println("为中秋节准备的促销活动B"); } }
class StrategyC extends Strategy{
@Override public void show() { System.out.println("为圣诞节准备的促销活动C"); } }
|
定义一个context,进行上下文感知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| class Context_SalesMan{
private Strategy strategy;
public SalesMan(String festival) { switch ( festival) { case "A": strategy = new StrategyA(); break; case "B": strategy = new StrategyB(); break; case "C": strategy = new StrategyC(); break; }
}
public void SalesManShow(){ strategy.show(); }
}
|
当我们具体使用的时候我们可以通过上下文去进行具体的调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class StrategyPattern{ public static void main(String[] args){
Context_SalesMan mSalesMan ;
System.out.println("对于春节:"); mSalesMan = Context_SalesMan SalesMan("A"); mSalesMan.SalesManShow(); System.out.println("对于中秋节:"); mSalesMan = Context_SalesMan SalesMan("B"); mSalesMan.SalesManShow();
System.out.println("对于圣诞节:"); mSalesMan = Context_SalesMan SalesMan("C"); mSalesMan.SalesManShow(); } }
|
优点: 我们只通过一个接口,就可以使得他们之间进行灵活的调用
增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“
适配器模式
场景:
有一个电源插座,现在国内的事220v的,希望有一个转接头能转换成110v的
首先我们先实现一个接口,代表我们期望使用的
1 2 3
| public interface Target { public void Convert_110v(); }
|
其次我们需要实现一个原有的插头
1 2 3 4 5
| class PowerPort220V{ public void output220v(); }
|
接下来我们需要创建一个adapter
1 2 3 4 5 6 7 8 9 10 11
| class Adapter220V extends PowerPort220V implements Target{
@Override public void Convert_110v(){ this.Output_220v; } }
|
此时我们可以直接去通过一个中间类(adapter去进行转换而不需要再去调用原有的220v的输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class ImportedMachine {
@Override public void Work() { System.out.println("进口机器正常运行"); } }
public class AdapterPattern { public static void main(String[] args){
Target mAdapter220V = new Adapter220V(); ImportedMachine mImportedMachine = new ImportedMachine(); mAdapter220V.Convert_110v(); mImportedMachine.Work(); } }
|
代理模式
背景: 我希望买个电脑,但是国内没有,我需要代购
首先我定义一个需要proxy做的事情
1 2 3 4
| public interface Subject{ public void buyMac(); }
|
创建一个真实的对象
1 2 3 4 5 6
| public class RealSubject implements Subject{ @Override public void buyMac(){ System.out.println("I buy"); } }
|
创建一个代理类,通过代理去进行实现,同时创建其对象,访问其中的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Proxy implements Subject{ @Override public void buyMac{ RealSubject realSubject = new RealSubject();
realSubject.buyMac(); this.WrapMac(); }
public void WrapMac(){ System.out.println(”用盒子包装好Mac“); } }
|
优势:
代理对象作为客户端和目标对象之间的中介,起到了保护目标对象的作用
协调调用者和被调用者,降低了系统的耦合度