设计模式
策略模式
介绍
定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法可以独立于使用它的客户变化。
结构
角色
- Context(环境类)
- Strategy(抽象策略类)
- Concrete Strategy(具体策略类)
实现
1 2 3 4
| public abstract class Strategy { public abstract void algorithm(); }
|
1 2 3 4 5 6 7
| public class ConcreteStrategyA extends Strategy { public void algorithm() { } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Context { private Strategy strategy; public void setStrategy(Strategy strategy) { this.strategy= strategy; }
public void algorithm() { strategy.algorithm(); } }
|
1 2 3 4 5 6 7 8 9
| …… Context context = new Context(); Strategy strategy; strategy = new ConcreteStrategyA(); context.setStrategy(strategy); context.algorithm(); ……
|
装饰器模式
介绍
在不改变一个对象本身功能的基础上给对象增加额外的新行为,引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩展原有类的功能
结构
角色
实现
1 2 3 4
| public abstract class Component { public abstract void display(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class ListBox extends Component { public void display() { System.out.println("显示列表框!"); } }
--------------------------------------------------------------------------
public class TextBox extends Component { public void display() { System.out.println("显示文本框!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ComponentDecorator extends Component { private Component component;
public ComponentDecorator(Component component) { this.component = component; }
public void display() { component.display(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class BlackBorderDecorator extends ComponentDecorator { public BlackBorderDecorator(Component component) { super(component); }
public void display() { this.setBlackBorder(); super.display(); }
public void setBlackBorder() { System.out.println("为构件增加黑色边框!"); } }
|
观察者模式
介绍
定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都得到通知并被自动更新。
结构
角色
- Subject(目标)
- Concrete Subject(具体目标)
- Observer(观察者)
- Concrete Observer(具体观察者)
实现
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
| public abstract class AllyControlCenter { protected String allyName; protected ArrayList<Observer> players = new ArrayList<Observer>();
public void setAllyName(String allyName) { this.allyName = allyName; }
public String getAllyName() { return this.allyName; }
public void join(Observer obs) { System.out.println(obs.getName() + "加入" + this.allyName + "战队!"); players.add(obs); }
public void quit(Observer obs) { System.out.println(obs.getName() + "退出" + this.allyName + "战队!"); players.remove(obs); }
public abstract void notifyObserver(String name); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class ConcreteAllyControlCenter extends AllyControlCenter { public ConcreteAllyControlCenter(String allyName) { System.out.println(allyName + "战队组建成功!"); System.out.println("----------------------------"); this.allyName = allyName; }
public void notifyObserver(String name) { System.out.println(this.allyName + "战队紧急通知,盟友" + name + "遭受敌人攻击!"); for(Object obs : players) { if (!((Observer)obs).getName().equalsIgnoreCase(name)) { ((Observer)obs).help(); } } } }
|
1 2 3 4 5 6 7
| public interface Observer { public String getName(); public void setName(String name); public void help(); public void beAttacked(AllyControlCenter acc); }
|
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
| public class Player implements Observer { private String name;
public Player(String name) { this.name = name; }
public void setName(String name) { this.name = name; }
public String getName() { return this.name; }
public void help() { System.out.println("坚持住," + this.name + "来救你!"); }
public void beAttacked(AllyControlCenter acc) { System.out.println(this.name + "被攻击!"); acc.notifyObserver(name); } }
|
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
| public class Client { public static void main(String args[]) { AllyControlCenter acc; acc = new ConcreteAllyControlCenter("金庸群侠");
Observer player1,player2,player3,player4,player5;
player1 = new Player("杨过"); acc.join(player1);
player2 = new Player("令狐冲"); acc.join(player2);
player3 = new Player("张无忌"); acc.join(player3);
player4 = new Player("段誉"); acc.join(player4);
player5 = new Player("郭靖"); acc.join(player5);
player2.beAttacked(acc); } }
|
适配器模式
介绍
适配器模式是一种结构型设计模式,旨在解决两个不兼容接口之间的兼容性问题。它允许将一个类的接口转换成客户端所期望的另一个接口
结构
角色
- Target(目标抽象类)
- Adapter(适配器类)
- Adaptee(适配者类)
实现
1 2 3 4 5 6
| public class AmbulanceLamp { public void alarmLamp() { System.out.println("呈现救护车灯闪烁!"); } }
|
1 2 3 4 5 6
| public class AmbulanceSound { public void alarmSound() { System.out.println("发出救护车声音!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class AmbulanceCarAdapter extends CarController { private AmbulanceSound sound; private AmbulanceLamp lamp;
public AmbulanceCarAdapter() { sound = new AmbulanceSound(); lamp = new AmbulanceLamp(); }
public void phonate() { sound.alarmSound(); }
public void twinkle() { lamp.alarmLamp(); } }
|
1 2 3 4 5 6 7 8 9 10
| public abstract class CarController { public void move() { System.out.println("玩具汽车移动!"); }
public abstract void phonate();
public abstract void twinkle(); }
|
抽象工厂模式
介绍
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。又称为工具(Kit)模式抽象工厂模式中的具体工厂不只是创建一种产品,它负责创建一族产品当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率
结构
角色
- Abstract Factory(抽象工厂)
- Concrete Factory(具体工厂)
- Abstract Product(抽象产品)
- Concrete Product(具体产品)
实现
三种抽象产品
1 2 3 4
| public interface Button { public void display(); }
|
1 2 3 4
| public interface ComboBox { public void display(); }
|
1 2 3 4
| public interface TextField { public void display(); }
|
抽象工厂
1 2 3 4 5
| public interface SkinFactory { public Button createButton(); public TextField createTextField(); public ComboBox createComboBox(); }
|
具体产品(部分)
1 2 3 4 5
| public class SpringButton implements Button { public void display() { System.out.println("显示浅绿色按钮。"); } }
|
1 2 3 4 5
| public class SpringComboBox implements ComboBox { public void display() { System.out.println("显示绿色边框组合框。"); } }
|
1 2 3 4 5
| public class SummerButton implements Button { public void display() { System.out.println("显示浅蓝色按钮。"); } }
|
1 2 3 4 5
| public class SummerComboBox implements ComboBox { public void display() { System.out.println("显示蓝色边框组合框。"); } }
|
具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SpringSkinFactory implements SkinFactory { public Button createButton() { return new SpringButton(); }
public TextField createTextField() { return new SpringTextField(); }
public ComboBox createComboBox() { return new SpringComboBox(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SummerSkinFactory implements SkinFactory { public Button createButton() { return new SummerButton(); }
public TextField createTextField() { return new SummerTextField(); }
public ComboBox createComboBox() { return new SummerComboBox(); } }
|
建造者模式
介绍
将一个复杂对象的==构建与它的表示分离==,使得同样的构建过程可以创建不同的表示。将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分与装配方式,只需要知道所需建造者的类型即可关注如何逐步创建一个复杂的对象,不同的建造者定义了不同的创建过程
结构
角色
- Builder(抽象建造者)
- Concrete Builder(具体建造者)
- Product(产品)
- Director(指挥者)
实现
1 2 3 4 5 6 7 8 9 10
| public class Actor { private String type; private String sex; private String face; private String costume; private String hairstyle;
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public abstract class ActorBuilder { protected Actor actor = new Actor();
public abstract void buildType();
public abstract void buildSex();
public abstract void buildFace();
public abstract void buildCostume();
public abstract void buildHairstyle();
public Actor createActor() { return actor; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class AngelBuilder extends ActorBuilder { public void buildType() { actor.setType("天使"); }
public void buildSex() { actor.setSex("女"); }
public void buildFace() { actor.setFace("漂亮"); }
public void buildCostume() { actor.setCostume("白裙"); }
public void buildHairstyle() { actor.setHairstyle("披肩长发"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ActorController { public Actor construct(ActorBuilder ab) { Actor actor; ab.buildType(); ab.buildSex(); ab.buildFace(); ab.buildCostume(); ab.buildHairstyle(); actor=ab.createActor(); return actor; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Client { public static void main(String args[]) { ActorBuilder ab; ab = (ActorBuilder)XMLUtil.getBean();
ActorController ac = new ActorController(); Actor actor;
actor = ac.construct(ab);
String type = actor.getType(); System.out.println(type + "的外观:"); System.out.println("性别:" + actor.getSex()); System.out.println("面容:" + actor.getFace()); System.out.println("服装:" + actor.getCostume()); System.out.println("发型:" + actor.getHairstyle()); } }
|
原型模式
介绍
使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象
结构
角色
- Prototype(抽象原型类)
- Concrete Prototype(具体原型类)
- Client(客户类)
实现
浅拷贝
(其中的引用对象相同)
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
| public class WeeklyLog implements Cloneable { private Attachment attachment; private String name; private String date; private String content;
public void setAttachment(Attachment attachment) { this.attachment = attachment; }
public void setName(String name) { this.name = name; }
public void setDate(String date) { this.date = date; }
public void setContent(String content) { this.content = content; }
public Attachment getAttachment() { return (this.attachment); }
public String getName() { return (this.name); }
public String getDate() { return (this.date); }
public String getContent() { return (this.content); }
public WeeklyLog clone() { Object obj = null; try { obj = super.clone(); return (WeeklyLog) obj; } catch (CloneNotSupportedException e) { System.out.println("不支持复制!"); return null; } } }
|
深拷贝
==(序列化与反序列化)==
序列化是将对象转换为字节流的过程,可以将对象保存到文件、传输到网络或在进程之间进行通信。在序列化过程中,对象的状态(即对象的数据)被转换为字节序列,包括对象的字段和相应的数值。序列化后的字节流可以被保存下来或传输给其他地方。
反序列化是将字节流转换为对象的过程,将保存在字节流中的数据重新构造成对象。在反序列化过程中,字节序列被还原为对象的状态,重新创建对象并将保存的数据填充到对象的字段中。
在写入字节流时,对象的所有字段都会被序列化为字节序列。而在读取字节流时,字节序列会被反序列化为一个新的对象,并将保存的数据填充到新对象的字段中。
由于反序列化过程会重新创建对象,因此新对象与原始对象是完全独立的,它们拥有相同的数据但是位于不同的内存位置。这样就实现了深拷贝,保留了对象及其所有引用类型字段的数据,并且不共享同一块内存。
需要注意的是,为了使对象能够进行序列化和反序列化,需要实现 Serializable
接口,并确保对象的所有引用类型字段也是可序列化的。
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
| public class WeeklyLog implements Serializable { private Attachment attachment; private String name; private String date; private String content;
public void setAttachment(Attachment attachment) { this.attachment = attachment; }
public void setName(String name) { this.name = name; }
public void setDate(String date) { this.date = date; }
public void setContent(String content) { this.content = content; }
public Attachment getAttachment() { return (this.attachment); }
public String getName() { return (this.name); }
public String getDate() { return (this.date); }
public String getContent() { return (this.content); }
public WeeklyLog deepClone() throws IOException, ClassNotFoundException, OptionalDataException { ByteArrayOutputStream bao=new ByteArrayOutputStream(); ObjectOutputStream oos=new ObjectOutputStream(bao); oos.writeObject(this);
ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray()); ObjectInputStream ois=new ObjectInputStream(bis); return (WeeklyLog)ois.readObject(); } }
|
单例模式
介绍
一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。
结构
角色
实现
饿汉式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Singleton { private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() { return instance; } }
|
懒汉式
多线程环境下可能会出现问题。如果多个线程同时访问getInstance()
方法,并且在instance
还未被创建时,那么每个线程都会通过判断instance
为null
的条件,并创建一个新的实例。这样就会破坏单例的唯一性,导致多个实例被创建。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class LazySingleton { private static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
|
通过synchronized
关键字修饰getInstance()
方法,以确保在多线程环境下只创建一个实例。当第一个线程调用getInstance()
方法时,如果实例尚未创建,它将创建一个新的实例
存在缺点:
- 每次调用
getInstance()
方法都会进入synchronized
同步块,即使实例已经被创建。这会造成不必要的同步开销,影响性能。
- 在多线程环境下,当多个线程同时通过第一个判断条件
instance == null
时,它们会依次进入synchronized
同步块,而只有一个线程能够创建实例,其他线程会被阻塞。这可能会引起线程竞争和性能问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class LazySingleton { private static LazySingleton instance = null;
private LazySingleton() { }
synchronized public static LazySingleton getInstance() { if (instance == null) { instance = new LazySingleton(); } return instance; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class LazySingleton { private volatile static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() { if (instance == null) { synchronized (LazySingleton.class) { if (instance == null) { instance = new LazySingleton(); } } } return instance; } }
|
静态内部类
==相关介绍==:
在静态内部类中定义的静态方法可以直接被调用,不需要通过创建内部类的实例来访问。静态内部类与外部类之间是独立的,因此可以直接访问静态内部类中的静态成员,包括静态方法。
在上述示例中,静态内部类HolderClass
中的instance
变量是私有静态的,而getInstance()
方法是公共静态的。这意味着可以通过Singleton.HolderClass.instance
直接访问instance
变量,也可以通过Singleton.getInstance()
调用getInstance()
方法来获取单例实例。这种方式提供了更简洁的访问方式,无需显式创建内部类实例。
需要注意的是,静态内部类中不能直接访问外部类的非静态成员,因为静态内部类在没有外部类实例的情况下也可以被访问。如果需要访问外部类的非静态成员,可以通过创建外部类的实例来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Singleton { private Singleton() { }
private static class HolderClass { private final static Singleton instance = new Singleton(); }
public static Singleton getInstance() { return HolderClass.instance; } }
|
1 2 3 4 5 6 7
| public class Main { public static void main(String[] args) { Singleton singleton = Singleton.getInstance(); } }
|
桥接模式
介绍
桥接模式是一种结构型设计模式,它旨在将抽象部分与其实现部分分离,使它们可以独立地变化。它通过创建一个桥接接口,将抽象和实现解耦,使它们可以独立地进行扩展。
在桥接模式中,存在两个维度的抽象和实现,通过桥接接口将它们连接起来。其中,抽象部分定义了高层的抽象方法和属性,而实现部分定义了具体实现的方法和属性。通过桥接接口,抽象部分和实现部分可以独立地进行扩展和变化,而彼此之间的关系通过桥接接口来实现。
结构
角色
- Abstraction(抽象类)
- Refined Abstraction(扩充抽象类)
- Implementor(实现类接口)
- Concrete Implementor(具体实现类)
实现
理解:通过桥接模式,图像实现类(如 LinuxImp
)和操作系统实现类(如 Linux
)被解耦,它们可以独立地变化和扩展。图像实现类负责将图像数据转换成特定格式(如像素矩阵),而操作系统实现类负责将像素矩阵在特定操作系统中进行显示。这样,通过注入不同的图像实现类和操作系统实现类,可以实现不同图像格式在不同操作系统下的显示,而不需要修改现有的类结构。
1 2 3 4 5 6 7 8 9 10 11 12 13
| public abstract class Image { protected ImageImp imp;
public void setImageImp(ImageImp imp) { this.imp = imp; }
public abstract void parseFile(String fileName); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
public class BMPImage extends Image { public void parseFile(String fileName) { Matrix m = new Matrix(); imp.doPaint(m); System.out.println(fileName + ",格式为BMP。"); } }
public class GIFImage extends Image { public void parseFile(String fileName) { Matrix m = new Matrix(); imp.doPaint(m); System.out.println(fileName + ",格式为GIF。"); } }
|
1 2 3 4
| public interface ImageImp { public void doPaint(Matrix m); }
|
1 2 3 4 5 6 7
| public class LinuxImp implements ImageImp { public void doPaint(Matrix m) { System.out.print("在Linux操作系统中显示图像:"); } }
|
1 2 3 4
| public class Matrix { }
|
状态模式
介绍
它允许对象在内部状态改变时改变其行为。该模式将对象的行为封装在不同的状态对象中,使得对象在不同状态下具有不同的行为,同时将状态的切换和行为的执行解耦。
结构
角色
Context(环境类)
State(抽象状态类)
Concrete State(具体状态类)
实现
具体的状态转换逻辑位于具体状态类中,每个状态类负责自己的状态转换和相应的操作
還有另外幾種狀態類的轉換方式 只提供對對應轉換方式代碼
1 2 3 4 5 6
| public abstract class SwitchState { public abstract void on(Switch s); public abstract void off(Switch s);
}
|
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
|
public class OnState extends SwitchState { public void on(Switch s) { System.out.println("已经打开!"); }
public void off(Switch s) { System.out.println("关闭!"); s.setState(Switch.getState("off")); } }
public class OffState extends SwitchState{ public void on(Switch s) { System.out.println("打开!"); s.setState(Switch.getState("on")); }
public void off(Switch s) { System.out.println("已经关闭!"); } }
|
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
| public class Switch { private static SwitchState currentState,onState,offState; private String name;
public Switch(String name) { this.name = name; onState = new OnState(); offState = new OffState(); currentState = onState; }
public void setState(SwitchState state) { currentState = state; }
public static SwitchState getState(String type) { if (type.equalsIgnoreCase("on")) { return onState; } else { return offState; } }
public void on() { System.out.print(name); currentState.on(this); }
public void off() { System.out.print(name); currentState.off(this); }
|
其餘轉換方式實現
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
|
public class Screen { private ScreenState currentState, normalState, largerState, largestState;
public Screen() { this.normalState = new NormalState(); this.largerState = new LargerState(); this.largestState = new LargestState(); this.currentState = normalState; this.currentState.display(); }
public void setState(ScreenState state) { this.currentState = state; }
public void onClick() { if (this.currentState == normalState) { this.setState(largerState); this.currentState.display(); } else if (this.currentState == largerState) { this.setState(largestState); this.currentState.display(); } else if (this.currentState == largestState) { this.setState(normalState); this.currentState.display(); } } }
|
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
| public class Account { private AccountState state; private String owner; private double balance = 0;
public Account(String owner,double init) { this.owner = owner; this.balance = balance; this.state = new NormalState(this); System.out.println(this.owner + "开户,初始金额为" + init); System.out.println("---------------------------------------------"); }
public double getBalance() { return this.balance; }
public void setBalance(double balance) { this.balance = balance; }
public void setState(AccountState state) { this.state = state; }
public void deposit(double amount) { System.out.println(this.owner + "存款" + amount); state.deposit(amount); System.out.println("现在余额为"+ this.balance); System.out.println("现在帐户状态为"+ this.state.getClass().getName()); System.out.println("---------------------------------------------"); }
public void withdraw(double amount) { System.out.println(this.owner + "取款" + amount); state.withdraw(amount); System.out.println("现在余额为"+ this.balance); System.out.println("现在帐户状态为"+ this. state.getClass().getName()); System.out.println("---------------------------------------------"); }
public void computeInterest() { state.computeInterest(); } }
|
1 2 3 4 5 6 7 8
| public abstract class AccountState { protected Account acc; public abstract void deposit(double amount); public abstract void withdraw(double amount); public abstract void computeInterest(); public abstract void stateCheck(); }
|
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
| public class NormalState extends AccountState { public NormalState(Account acc) { this.acc = acc; }
public NormalState(AccountState state) { this.acc = state.acc; }
public void deposit(double amount) { acc.setBalance(acc.getBalance() + amount); stateCheck(); }
public void withdraw(double amount) { acc.setBalance(acc.getBalance() - amount); stateCheck(); }
public void computeInterest() { System.out.println("正常状态,无须支付利息!"); }
public void stateCheck() { if (acc.getBalance() > -2000 && acc.getBalance() <= 0) { acc.setState(new OverdraftState(this)); } else if (acc.getBalance() == -2000) { acc.setState(new RestrictedState(this)); } else if (acc.getBalance() < -2000) { System.out.println("操作受限!"); } } }
|
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
| public class OverdraftState extends AccountState { public OverdraftState(AccountState state) { this.acc = state.acc; }
public void deposit(double amount) { acc.setBalance(acc.getBalance() + amount); stateCheck(); }
public void withdraw(double amount) { acc.setBalance(acc.getBalance() - amount); stateCheck(); }
public void computeInterest() { System.out.println("计算利息!"); }
public void stateCheck() { if (acc.getBalance() > 0) { acc.setState(new NormalState(this)); } else if (acc.getBalance() == -2000) { acc.setState(new RestrictedState(this)); } else if (acc.getBalance() < -2000) { System.out.println("操作受限!"); } } }
|
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
| public class RestrictedState extends AccountState { public RestrictedState(AccountState state) { this.acc = state.acc; }
public void deposit(double amount) { acc.setBalance(acc.getBalance() + amount); stateCheck(); }
public void withdraw(double amount) { System.out.println("帐号受限,取款失败"); }
public void computeInterest() { System.out.println("计算利息!"); }
public void stateCheck() { if(acc.getBalance() > 0) { acc.setState(new NormalState(this)); } else if(acc.getBalance() > -2000) { acc.setState(new OverdraftState(this)); } } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Client { public static void main(String args[]) { Account acc = new Account("段誉",0.0); acc.deposit(1000); acc.withdraw(2000); acc.deposit(3000); acc.withdraw(4000); acc.withdraw(1000); acc.computeInterest(); } }
|
命令模式
介绍
命令模式(Command Pattern)用于将请求(命令)封装成一个对象,使得可以将不同的请求参数化并且支持请求的排队、记录日志、撤销等操作
结构
角色
- 命令接口(Command)
- 具体命令(Concrete Command)
- 命令接收者(Receiver)
- 命令发起者(Invoker)
实现
1 2 3 4
| public abstract class Command { public abstract void execute(); }
|
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
|
public class HelpCommand extends Command { private DisplayHelpClass hcObj;
public HelpCommand() { hcObj = new DisplayHelpClass(); }
public void execute() { hcObj.display(); } }
public class ExitCommand extends Command { private SystemExitClass seObj;
public ExitCommand() { seObj = new SystemExitClass(); }
public void execute() { seObj.exit(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
|
public class DisplayHelpClass { public void display() { System.out.println("显示帮助文档!"); } }
public class SystemExitClass { public void exit() { System.out.println("退出系统!"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class FunctionButton { private Command command;
public void setCommand(Command command) { this.command = command; }
public void click() { System.out.print("单击功能键: "); command.execute(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class Client { public static void main(String args[]) {
FunctionButton fb = new FunctionButton();
Command command; command = (Command)XMLUtil.getBean();
fb.setCommand(command); fb.click(); } }
|
組合模式
介紹
组合模式是一种结构型设计模式,用于将对象组合成树形结构以表示”部分-整体”的层次关系,使得用户对单个对象和组合对象的使用具有一致性。
結構
角色
- 组件(Component):是组合中的抽象基类,定义了组合对象和叶子对象的共有操作接口。它可以是抽象类或接口,声明了一些用于管理子对象的方法,例如添加、删除、获取子对象等。
- 叶子(Leaf):是组合中的叶子节点,表示组合对象中的基本元素,它没有子对象。
- 容器(Composite):是组合中的容器节点,表示可以包含子对象的复杂对象。容器对象中通常会持有一个或多个子对象,并实现组合对象的共有操作接口。容器对象的操作会递归地调用子对象的操作,以实现对整个树形结构的操作。
- 客户端(Client):通过组合对象的操作接口来操作组合对象和叶子对象。
實現
1 2 3 4 5 6 7
| public abstract class AbstractFile { public abstract void add(AbstractFile file); public abstract void remove(AbstractFile file); public abstract AbstractFile getChild(int i); public abstract void killVirus(); }
|
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
| public class Folder extends AbstractFile { private ArrayList<AbstractFile> fileList=new ArrayList<AbstractFile>(); private String name;
public Folder(String name) { this.name = name; }
public void add(AbstractFile file) { fileList.add(file); }
public void remove(AbstractFile file) { fileList.remove(file); }
public AbstractFile getChild(int i) { return (AbstractFile)fileList.get(i); }
public void killVirus() { System.out.println("****对文件夹'" + name + "'进行杀毒");
for(Object obj : fileList) { ((AbstractFile)obj).killVirus(); } }
|
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
public class ImageFile extends AbstractFile { private String name;
public ImageFile(String name) { this.name = name; }
public void add(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public void remove(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public AbstractFile getChild(int i) { System.out.println("对不起,不支持该方法!"); return null; }
public void killVirus() { System.out.println("----对图像文件'" + name + "'进行杀毒"); } }
public class TextFile extends AbstractFile { private String name;
public TextFile(String name) { this.name = name; }
public void add(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public void remove(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public AbstractFile getChild(int i) { System.out.println("对不起,不支持该方法!"); return null; }
public void killVirus() { System.out.println("----对文本文件'" + name + "'进行杀毒"); } }
public class VideoFile extends AbstractFile { private String name;
public VideoFile(String name) { this.name = name; }
public void add(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public void remove(AbstractFile file) { System.out.println("对不起,不支持该方法!"); }
public AbstractFile getChild(int i) { System.out.println("对不起,不支持该方法!"); return null; }
public void killVirus() { System.out.println("----对视频文件'" + name + "'进行杀毒"); } }
|
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
| public class Client { public static void main(String args[]) { AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;
folder1 = new Folder("Sunny的资料"); folder2 = new Folder("图像文件"); folder3 = new Folder("文本文件"); folder4 = new Folder("视频文件");
file1 = new ImageFile("小龙女.jpg"); file2 = new ImageFile("张无忌.gif"); file3 = new TextFile("九阴真经.txt"); file4 = new TextFile("葵花宝典.doc"); file5 = new VideoFile("笑傲江湖.rmvb");
folder2.add(file1); folder2.add(file2); folder3.add(file3); folder3.add(file4); folder4.add(file5);
folder1.add(folder2); folder1.add(folder3); folder1.add(folder4);
folder1.killVirus(); } }
|
模式(模板)
介紹
結構
角色
實現