Java面試二(設計模式)
基礎二
設計模式概要
建立型模式
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;