基础二
设计模式概要
创建型模式
1. 单例模式
一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
2. 工厂模式
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
比如你和老板去饭店吃鲍鱼,直接和酒店说要鲍鱼就可以了;酒店负责采购,做鲍鱼;这样我们就不用自己做鲍鱼了,也就实现了把客户和服务分开。
3. 抽象工厂模式
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
比如我请个妹子去饭店吃饭,但是不知道妹子喜好。这样我们就把妹子带到酒店,点餐的时候让妹子点她喜欢吃的。这样也实现了工厂模式,但是我不必关心妹子喜欢吃什么,而让妹子决定吃什么。
4. 建筑者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如去吃龙虾,龙虾有清蒸,刺身,生姜三种做法,其实三种做法有些步骤做法是相同的,比如洗龙虾,蒸龙虾,但是步骤不同。而且我们想吃的时候去点就可以,不用关心怎么做。
建造者模式最主要的功能是基本方法的调用顺序安排,这些基本方法已经实现了,顺序不同产生的对象也不同;
工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。
5. 原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。即实现Cloneable接口,重写clone()方法。
跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了。
结构型模式
1. 适配器模式
你要给苹果手机充电,但是苹果你只有一个android手机的USB,这个时候同事借给你一个TP3.0 转 苹果 充电头的东西,这个东西就是一个适配器。
2. 桥接模式
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
早上碰到MM,要说早上好,晚上碰到MM,要说晚上好;碰到MM穿了件新衣服,要说你的衣服好漂亮哦,碰到MM新做的发型,要说你的头发好漂亮哦。
不要问我“早上碰到MM新做了个发型怎么说”这种问题,自己用BRIDGE组合一下不就行了。
3. 组合模式
Mary今天过生日。
“我过生日,你要送我一件礼物。”
“嗯,好吧,去商店,你自己挑。”
“这件T恤挺漂亮,买,这条裙子好看,买,这个包也不错,买。”
“喂,买了三件了呀,我只答应送一件礼物的哦。”
“什么呀,T恤加裙子加包包,正好配成一套呀,小姐,麻烦你包起来。 ”
“……”
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
4. 装饰模式
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。
Mary过完轮到Sarly过生日,还是不要叫她自己挑了,不然这个月伙食费肯定玩完,拿出我去年在华山顶上照的照片,在背面写上“最好的的礼物,就是爱你的Fita”,再到街上礼品店买了个像框,再找隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来……,其他的人都是Decorator,最终都在修饰我这个人呀。
5. 外观模式
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系统更易于使用。每一个子系统只有一个门面类,而且此门面类只有一个实例,也就是说它是一个单例模式。但整个系统可以有多个门面类。
6. 享元模式
主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。
享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。
FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。
7. 代理模式
为其他对象提供一种代理以控制对这个对象的访问。
行为型模式
1. 模板方法模式
做一个模板,在模板中定义好调用顺序,调用方法。不同的子类实现各自特点的方法,然后外部访问的时候访问子类的调用方法。
2. 责任链模式
追责问题,我去买楼,售楼小姐处理不了找经理,经理处理不了找副总,副总处理不了找老总。找到能负责这个部分的人为止。
3. 命令模式
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
4. 迭代器模式
迭代子模式:迭代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起形成的总体称之为聚集,聚集对象是能够包容一组对象的容器对象。迭代子模式将迭代逻辑封装到一个独立的子对象中,从而与聚集本身隔开。迭代子模式简化了聚集的界面。每一个聚集对象都可以有一个或一个以上的迭代子对象,每一个迭代子的迭代状态可以是彼此独立的。迭代算法可以独立于聚集角色变化。
5. 中介者模式
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
6. 备忘录模式
备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。
7. 观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
8. 状态模式
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
跟MM交往时,一定要注意她的状态哦,在不同的状态时她的行为会有不同,比如你约她今天晚上去看电影,对你没兴趣的MM就会说 “有事情啦”,对你不讨厌但还没喜欢上的MM就会说“好啊,不过可以带上我同事么?”,已经喜欢上你的MM就会说“几点钟?看完电影再去泡吧怎么样?”
9. 策略模式
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
比如int[]排序有冒泡,选择排序,归并,堆等等算法,每一个算法都是一个Strategy,把这些策略都封装起来根据并可以独立使用。
10. 访问者模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
11. 解释器模式
俺有一个《泡MM真经》,上面有各种泡MM的攻略,比如说去吃西餐的步骤、去看电影的方法等等,跟MM约会时,只要做一个Interpreter,照着上面的脚本执行就可以了。
解释器模式:给定一个语言后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。解释器模式将描述怎样在有了一个简单的文法后,使用模式设计解释这些语句。在解释器模式里面提到的语言是指任何解释器对象能够解释的任何组合。在解释器模式中需要定义一个代表文法的命令类的等级结构,也就是一系列的组合规则。每一个命令对象都有一个解释方法,代表对命令对象的解释。命令对象的等级结构中的对象的任何排列组合都是一个语言。
单例模式实例
代码来自:
sample 1 恶汉模式
public final class InitializingOnDemandHolderIdiom {
/**
* Private constructor.
*/
private InitializingOnDemandHolderIdiom() {
}
/**
* @return Singleton instance
*/
public static InitializingOnDemandHolderIdiom getInstance() {
return HelperHolder.INSTANCE;
}
/**
* Provides the lazy-loaded Singleton instance.
*/
private static class HelperHolder {
private static final InitializingOnDemandHolderIdiom INSTANCE =
new InitializingOnDemandHolderIdiom();
}
}
sample 2 懒汉模式
public final class ThreadSafeDoubleCheckLocking {
private static volatile ThreadSafeDoubleCheckLocking instance;
/**
* private constructor to prevent client from instantiating.
*/
private ThreadSafeDoubleCheckLocking() {
// to prevent instantiating by Reflection call
if (instance != null) {
throw new IllegalStateException("Already initialized.");
}
}
/**
* Public accessor.
*
* @return an instance of the class.
*/
public static ThreadSafeDoubleCheckLocking getInstance() {
// local variable increases performance by 25 percent
// Joshua Bloch "Effective Java, Second Edition", p. 283-284
ThreadSafeDoubleCheckLocking result = instance;
// Check if singleton instance is initialized. If it is initialized then we can return the instance.
if (result == null) {
// It is not initialized but we cannot be sure because some other thread might have initialized it
// in the meanwhile. So to make sure we need to lock on an object to get mutual exclusion.
synchronized (ThreadSafeDoubleCheckLocking.class) {
// Again assign the instance to local variable to check if it was initialized by some other thread
// while current thread was blocked to enter the locked zone. If it was initialized then we can
// return the previously created instance just like the previous null check.
result = instance;
if (result == null) {
// The instance is still not initialized so we can safely (no other thread can enter this zone)
// create an instance and make it our singleton instance.
instance = result = new ThreadSafeDoubleCheckLocking();
}
}
}
return result;
}
}
public final class ThreadSafeLazyLoadedIvoryTower {
private static ThreadSafeLazyLoadedIvoryTower instance;
private ThreadSafeLazyLoadedIvoryTower() {
// protect against instantiation via reflection
if (instance == null) {
instance = this;
} else {
throw new IllegalStateException("Already initialized.");
}
}
/**
* The instance gets created only when it is called for first time. Lazy-loading
*/
public static synchronized ThreadSafeLazyLoadedIvoryTower getInstance() {
if (instance == null) {
instance = new ThreadSafeLazyLoadedIvoryTower();
}
return instance;
}
}
工厂模式
factory kit
Weapon是武器;Axe是斧头;Bow是弓;Spear是矛,枪;Sword是剑。
WarponType是武器类型。
WeaponFactory是武器工厂,Builder是武器工人。
/**
* Interface representing weapon.
*/
public interface Weapon {
}
/**
* Enumerates {@link Weapon} types
*/
public enum WeaponType {
SWORD, AXE, BOW, SPEAR
}
/**
* Class representing Axe
*/
public class Axe implements Weapon {
@Override
public String toString() {
return "Axe";
}
}
/**
* Class representing Bows
*/
public class Bow implements Weapon {
@Override
public String toString() {
return "Bow";
}
}
/**
* Class representing Spear
*/
public class Spear implements Weapon {
@Override
public String toString() {
return "Spear";
}
}
/**
* Class representing Swords
*/
public class Sword implements Weapon {
@Override
public String toString() {
return "Sword";
}
}
/**
* Functional interface, an example of the factory-kit design pattern.
* <br>Instance created locally gives an opportunity to strictly define
* which objects types the instance of a factory will be able to create.
* <br>Factory is a placeholder for {@link Builder}s
* with {@link WeaponFactory#create(WeaponType)} method to initialize new objects.
*/
public interface WeaponFactory {
/**
* Creates an instance of the given type.
* @param name representing enum of an object type to be created.
* @return new instance of a requested class implementing {@link Weapon} interface.
*/
Weapon create(WeaponType name);
/**
* Creates factory - placeholder for specified {@link Builder}s.
* @param consumer for the new builder to the factory.
* @return factory with specified {@link Builder}s
*/
static WeaponFactory factory(Consumer<Builder> consumer) {
Map<WeaponType, Supplier<Weapon>> map = new HashMap<>();
consumer.accept(map::put);
return name -> map.get(name).get();
}
}
/**
* Functional interface that allows adding builder with name to the factory.
*/
public interface Builder {
void add(WeaponType name, Supplier<Weapon> supplier);
}
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
WeaponFactory factory = WeaponFactory.factory(builder -> {
builder.add(WeaponType.SWORD, Sword::new);
builder.add(WeaponType.AXE, Axe::new);
builder.add(WeaponType.SPEAR, Spear::new);
builder.add(WeaponType.BOW, Bow::new);
});
Weapon axe = factory.create(WeaponType.AXE);
LOGGER.info(axe.toString());
}
}
运行结果。
factory method
Blacksmith是铁匠;OrcBlacksmith是魔法铁匠;ElfBlacksmith是精灵铁匠。
Weapon是武器;Weapon是武器类型;ElfWeapon是精灵武器;OrcWeapon是魔法武器。
OrcBlacksmith是魔法武器工厂;ElfBlacksmith是精灵武器工厂;这里铁匠是总武器工厂。
/**
*
* WeaponType enumeration
*
*/
public enum WeaponType {
SHORT_SWORD("short sword"), SPEAR("spear"), AXE("axe"), UNDEFINED("");
private String title;
WeaponType(String title) {
this.title = title;
}
@Override
public String toString() {
return title;
}
}
public interface Weapon {
WeaponType getWeaponType();
}
public class OrcWeapon implements Weapon {
private WeaponType weaponType;
public OrcWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
@Override
public String toString() {
return "Orcish " + weaponType;
}
@Override
public WeaponType getWeaponType() {
return weaponType;
}
}
public class ElfWeapon implements Weapon {
private WeaponType weaponType;
public ElfWeapon(WeaponType weaponType) {
this.weaponType = weaponType;
}
@Override
public String toString() {
return "Elven " + weaponType;
}
@Override
public WeaponType getWeaponType() {
return weaponType;
}
}
public interface Blacksmith {
Weapon manufactureWeapon(WeaponType weaponType);
}
public class ElfBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return new ElfWeapon(weaponType);
}
}
public class OrcBlacksmith implements Blacksmith {
public Weapon manufactureWeapon(WeaponType weaponType) {
return new OrcWeapon(weaponType);
}
}
/**
*
* The Factory Method is a creational design pattern which uses factory methods to deal with the
* problem of creating objects without specifying the exact class of object that will be created.
* This is done by creating objects via calling a factory method either specified in an interface
* and implemented by child classes, or implemented in a base class and optionally overridden by
* derived classes—rather than by calling a constructor.
* <p>
* In this Factory Method example we have an interface ({@link Blacksmith}) with a method for
* creating objects ({@link Blacksmith#manufactureWeapon}). The concrete subclasses (
* {@link OrcBlacksmith}, {@link ElfBlacksmith}) then override the method to produce objects of
* their liking.
*
*/
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private final Blacksmith blacksmith;
/**
* Creates an instance of <code>App</code> which will use <code>blacksmith</code> to manufacture
* the weapons for war.
* <code>App</code> is unaware which concrete implementation of {@link Blacksmith} it is using.
* The decision of which blacksmith implementation to use may depend on configuration, or
* the type of rival in war.
* @param blacksmith a non-null implementation of blacksmith
*/
public App(Blacksmith blacksmith) {
this.blacksmith = blacksmith;
}
/**
* Program entry point
*
* @param args command line args
*/
public static void main(String[] args) {
// Lets go to war with Orc weapons
App app = new App(new OrcBlacksmith());
app.manufactureWeapons();
// Lets go to war with Elf weapons
app = new App(new ElfBlacksmith());
app.manufactureWeapons();
}
private void manufactureWeapons() {
Weapon weapon;
weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
LOGGER.info(weapon.toString());
weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
LOGGER.info(weapon.toString());
}
}
abstract-factory
Army是军队;Castle是城堡;King是国王。
OrcArmy是魔军队;OrcCastle是魔城堡;OrcKing是魔王。
ElfArmy是精灵军队;ElfCastle是精灵城堡;ElfKing是精灵王。
KingdomFactory是王国工厂;OrcKingdomFactory是魔王国;ElfKingdomFactory是精灵王国。
public interface Army {
String getDescription();
}
public interface Castle {
String getDescription();
}
public interface King {
String getDescription();
}
public class OrcArmy implements Army {
static final String DESCRIPTION = "This is the Orc Army!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class OrcCastle implements Castle {
static final String DESCRIPTION = "This is the Orc castle!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class OrcKing implements King {
static final String DESCRIPTION = "This is the Orc king!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfArmy implements Army {
static final String DESCRIPTION = "This is the Elven Army!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfCastle implements Castle {
static final String DESCRIPTION = "This is the Elven castle!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfKing implements King {
static final String DESCRIPTION = "This is the Elven king!";
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public interface KingdomFactory {
Castle createCastle();
King createKing();
Army createArmy();
}
public class OrcKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new OrcCastle();
}
public King createKing() {
return new OrcKing();
}
public Army createArmy() {
return new OrcArmy();
}
}
public class ElfKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new ElfCastle();
}
public King createKing() {
return new ElfKing();
}
public Army createArmy() {
return new ElfArmy();
}
}
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private King king;
private Castle castle;
private Army army;
/**
* Creates kingdom
*/
public void createKingdom(final KingdomFactory factory) {
setKing(factory.createKing());
setCastle(factory.createCastle());
setArmy(factory.createArmy());
}
King getKing(final KingdomFactory factory) {
return factory.createKing();
}
public King getKing() {
return king;
}
private void setKing(final King king) {
this.king = king;
}
Castle getCastle(final KingdomFactory factory) {
return factory.createCastle();
}
public Castle getCastle() {
return castle;
}
private void setCastle(final Castle castle) {
this.castle = castle;
}
Army getArmy(final KingdomFactory factory) {
return factory.createArmy();
}
public Army getArmy() {
return army;
}
private void setArmy(final Army army) {
this.army = army;
}
/**
* Program entry point
*
* @param args
* command line args
*/
public static void main(String[] args) {
App app = new App();
LOGGER.info("Elf Kingdom");
app.createKingdom(new ElfKingdomFactory());
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
LOGGER.info("Orc Kingdom");
app.createKingdom(new OrcKingdomFactory());
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
}
}
原型模式 prototype
Prototype是原型。
Beast是野兽;ElfBeast精灵野兽;OrcBeast是魔野兽。
Warlord是军阀;ElfWarlord是精灵军;OrcWarlord是魔军。
Mage是魔法师;ElfMage是精灵魔法师;OrcMage是魔鬼魔法师。
HeroFactoryImpl是英雄工厂。
public abstract class Prototype implements Cloneable {
@Override
public abstract Object clone() throws CloneNotSupportedException;
}
public abstract class Warlord extends Prototype {
@Override
public abstract Warlord clone() throws CloneNotSupportedException;
}
public abstract class Mage extends Prototype {
@Override
public abstract Mage clone() throws CloneNotSupportedException;
}
public abstract class Beast extends Prototype {
@Override
public abstract Beast clone() throws CloneNotSupportedException;
}
public class OrcBeast extends Beast {
public OrcBeast() {}
@Override
public Beast clone() throws CloneNotSupportedException {
return new OrcBeast();
}
@Override
public String toString() {
return "Orcish wolf";
}
}
public class OrcMage extends Mage {
public OrcMage() {}
@Override
public Mage clone() throws CloneNotSupportedException {
return new OrcMage();
}
@Override
public String toString() {
return "Orcish mage";
}
}
public class OrcBeast extends Beast {
public OrcBeast() {}
@Override
public Beast clone() throws CloneNotSupportedException {
return new OrcBeast();
}
@Override
public String toString() {
return "Orcish wolf";
}
}
public class ElfBeast extends Beast {
public ElfBeast() {}
@Override
public Beast clone() throws CloneNotSupportedException {
return new ElfBeast();
}
@Override
public String toString() {
return "Elven eagle";
}
}
public class ElfMage extends Mage {
public ElfMage() {}
@Override
public Mage clone() throws CloneNotSupportedException {
return new ElfMage();
}
@Override
public String toString() {
return "Elven mage";
}
}
public class ElfWarlord extends Warlord {
public ElfWarlord() {}
@Override
public Warlord clone() throws CloneNotSupportedException {
return new ElfWarlord();
}
@Override
public String toString() {
return "Elven warlord";
}
}
public interface HeroFactory {
Mage createMage();
Warlord createWarlord();
Beast createBeast();
}
public class HeroFactoryImpl implements HeroFactory {
private Mage mage;
private Warlord warlord;
private Beast beast;
/**
* Constructor
*/
public HeroFactoryImpl(Mage mage, Warlord warlord, Beast beast) {
this.mage = mage;
this.warlord = warlord;
this.beast = beast;
}
/**
* Create mage
*/
public Mage createMage() {
try {
return mage.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* Create warlord
*/
public Warlord createWarlord() {
try {
return warlord.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* Create beast
*/
public Beast createBeast() {
try {
return beast.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
}
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/**
* Program entry point
*
* @param args command line args
*/
public static void main(String[] args) {
HeroFactory factory;
Mage mage;
Warlord warlord;
Beast beast;
factory = new HeroFactoryImpl(new ElfMage(), new ElfWarlord(), new ElfBeast());
mage = factory.createMage();
warlord = factory.createWarlord();
beast = factory.createBeast();
LOGGER.info(mage.toString());
LOGGER.info(warlord.toString());
LOGGER.info(beast.toString());
factory = new HeroFactoryImpl(new OrcMage(), new OrcWarlord(), new OrcBeast());
mage = factory.createMage();
warlord = factory.createWarlord();
beast = factory.createBeast();
LOGGER.info(mage.toString());
LOGGER.info(warlord.toString());
LOGGER.info(beast.toString());
}
}
代理模式 Proxy
IvoryTower是象牙塔;Wizard是男巫/男骑士;WizardTower是巫术塔;WizardTowerProxy是巫术塔代理。
public interface WizardTower {
void enter(Wizard wizard);
}
public class Wizard {
private final String name;
public Wizard(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public class IvoryTower implements WizardTower {
private static final Logger LOGGER = LoggerFactory.getLogger(IvoryTower.class);
public void enter(Wizard wizard) {
LOGGER.info("{} enters the tower.", wizard);
}
}
public class WizardTowerProxy implements WizardTower {
private static final Logger LOGGER = LoggerFactory.getLogger(WizardTowerProxy.class);
private static final int NUM_WIZARDS_ALLOWED = 3;
private int numWizards;
private final WizardTower tower;
public WizardTowerProxy(WizardTower tower) {
this.tower = tower;
}
@Override
public void enter(Wizard wizard) {
if (numWizards < NUM_WIZARDS_ALLOWED) {
tower.enter(wizard);
numWizards++;
} else {
LOGGER.info("{} is not allowed to enter!", wizard);
}
}
}
public static void main(String[] args) {
WizardTowerProxy proxy = new WizardTowerProxy(new IvoryTower());
proxy.enter(new Wizard("Red wizard"));
proxy.enter(new Wizard("White wizard"));
proxy.enter(new Wizard("Black wizard"));
proxy.enter(new Wizard("Green wizard"));
proxy.enter(new Wizard("Brown wizard"));
}
最后运行的结果是:
20:56:08.346 [main] INFO com.iluwatar.proxy.IvoryTower - Red wizard enters the tower.
20:56:08.352 [main] INFO com.iluwatar.proxy.IvoryTower - White wizard enters the tower.
20:56:08.352 [main] INFO com.iluwatar.proxy.IvoryTower - Black wizard enters the tower.
20:56:08.352 [main] INFO com.iluwatar.proxy.WizardTowerProxy - Green wizard is not allowed to enter!
20:56:08.352 [main] INFO com.iluwatar.proxy.WizardTowerProxy - Brown wizard is not allowed to enter!
委派模式 Delegate
class RealPrinter { // the "delegate"
void print() {
System.out.print("something");
}
}
class Printer { // the "delegator"
RealPrinter p = new RealPrinter(); // create the delegate
void print() {
p.print(); // delegation
}
}
public class Main {
// to the outside world it looks like Printer actually prints.
public static void main(String[] args) {
Printer printer = new Printer();
printer.print();
}
}
代理(Proxy)是名词,委派(Delegate)是动词,其次代理说明了若干个对象实现了一个共同的接口,而委派只是说明一个对象引用了另一个对象,并不牵扯接口。
proxy :译为代理, 被代理方(B)与代理方(A)的接口完全一致。 主要使用场景(语义)应该是:为简化编程(或无法操作B),不直接把请求交给被代理方(B),而把请求交给代码方(A),由代理方与被代理方进行通信,以完成请求。
delegete : 译为委托,主要语义是:一件事情(或一个请求)对象本身不知道怎样处理,对象把请求交给其它对象来做。
策略模式 Strategy
DragonSlayingStrategy杀龙策略;ProjectileStrategy射击策略;Melee格斗策略;SpellStrategy符咒策略。
DragonSlayer屠龙者。
@FunctionalInterface
public interface DragonSlayingStrategy {
void execute();
}
public class MeleeStrategy implements DragonSlayingStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(MeleeStrategy.class);
@Override
public void execute() {
LOGGER.info("With your Excalibur you sever the dragon's head!");
}
}
public class ProjectileStrategy implements DragonSlayingStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(ProjectileStrategy.class);
@Override
public void execute() {
LOGGER.info("You shoot the dragon with the magical crossbow and it falls dead on the ground!");
}
}
public class SpellStrategy implements DragonSlayingStrategy {
private static final Logger LOGGER = LoggerFactory.getLogger(SpellStrategy.class);
@Override
public void execute() {
LOGGER.info("You cast the spell of disintegration and the dragon vaporizes in a pile of dust!");
}
}
public class DragonSlayer {
private DragonSlayingStrategy strategy;
public DragonSlayer(DragonSlayingStrategy strategy) {
this.strategy = strategy;
}
public void changeStrategy(DragonSlayingStrategy strategy) {
this.strategy = strategy;
}
public void goToBattle() {
strategy.execute();
}
}
public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
// GoF Strategy pattern
LOGGER.info("Green dragon spotted ahead!");
DragonSlayer dragonSlayer = new DragonSlayer(new MeleeStrategy());
dragonSlayer.goToBattle();
LOGGER.info("Red dragon emerges.");
dragonSlayer.changeStrategy(new ProjectileStrategy());
dragonSlayer.goToBattle();
LOGGER.info("Black dragon lands before you.");
dragonSlayer.changeStrategy(new SpellStrategy());
dragonSlayer.goToBattle();
// Java 8 Strategy pattern
LOGGER.info("Green dragon spotted ahead!");
dragonSlayer = new DragonSlayer(
() -> LOGGER.info("With your Excalibur you severe the dragon's head!"));
dragonSlayer.goToBattle();
LOGGER.info("Red dragon emerges.");
dragonSlayer.changeStrategy(() -> LOGGER.info(
"You shoot the dragon with the magical crossbow and it falls dead on the ground!"));
dragonSlayer.goToBattle();
LOGGER.info("Black dragon lands before you.");
dragonSlayer.changeStrategy(() -> LOGGER.info(
"You cast the spell of disintegration and the dragon vaporizes in a pile of dust!"));
dragonSlayer.goToBattle();
}
}
结果
21:26:47.571 [main] INFO com.iluwatar.strategy.App - Green dragon spotted ahead!
21:26:47.578 [main] INFO com.iluwatar.strategy.MeleeStrategy - With your Excalibur you sever the dragon's head!
21:26:47.579 [main] INFO com.iluwatar.strategy.App - Red dragon emerges.
21:26:47.579 [main] INFO com.iluwatar.strategy.ProjectileStrategy - You shoot the dragon with the magical crossbow and it falls dead on the ground!
21:26:47.579 [main] INFO com.iluwatar.strategy.App - Black dragon lands before you.
21:26:47.580 [main] INFO com.iluwatar.strategy.SpellStrategy - You cast the spell of disintegration and the dragon vaporizes in a pile of dust!
21:26:47.580 [main] INFO com.iluwatar.strategy.App - Green dragon spotted ahead!
21:26:47.580 [main] INFO com.iluwatar.strategy.App - With your Excalibur you severe the dragon's head!
21:26:47.580 [main] INFO com.iluwatar.strategy.App - Red dragon emerges.
21:26:47.581 [main] INFO com.iluwatar.strategy.App - You shoot the dragon with the magical crossbow and it falls dead on the ground!
21:26:47.581 [main] INFO com.iluwatar.strategy.App - Black dragon lands before you.
21:26:47.581 [main] INFO com.iluwatar.strategy.App - You cast the spell of disintegration and the dragon vaporizes in a pile of dust!