1、根据目的来分
根据模式是用来完成什么工作的来划分,这种方式可分为创建型模式、结构型模式和行为型模式3种。
创建型模式:
用于描述怎样创建对象,他的主要特点是 “将对象的创建于使用分离”,GoF 中提供了单例、原型、工厂方法、抽象工厂、建造者等5种模式。
结构型模式:
用于描述如何将类或对象按某种布局组成更大的结构,GoF 中提供了代理、适配器、桥接、装饰、外观、享元、组合等 7 种结构型模式。
行为型模式:
用于描述类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,以及怎样分配职责,GoF 中提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器等 11 种行为型模式。
2、根据作用范围来分
类模式:
用于处理类于子类之间的关系,这些关系通过继承来建立,是静态的,在编译时刻便确定下来。GoF中的工厂方法、(类)适配器、模板方法、解释器属于该模式。
对象模式:
用于处理对象之间的关系,这些关系可以通过组合或聚合来实现,在运行时刻是可以变化的,更具有动态性。GoF 中除了以上 4 种,其他的都是对象模式。
范围\目的 | 创建型模式 | 结构型模式 | 行为型模式 |
---|---|---|---|
类模式 | 工厂方法 | (类)适配器 | 模板方法、解释器 |
对象模式 | 单例 原型 抽象工厂 建造者 | 代理 (对象)适配器 桥接 装饰 外观 享元 组合 | 策略 命令 职责链 状态 观察者 中介者 迭代器 访问者 备忘录 |
3、 GoF的23种设计模式的功能
- 单例模式:
public class Singleton {
private Singleton() {}
public static Singleton getInstance(){
return Inner.singleton;
}
public static class Inner{
private static final Singleton singleton = new Singleton();
}
}
某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是多例模式。
- 原型模式:
//具体原型类
class Realizetype implements Cloneable
{
Realizetype()
{
System.out.println("具体原型创建成功!");
}
public Object clone() throws CloneNotSupportedException
{
System.out.println("具体原型复制成功!");
return (Realizetype)super.clone();
}
}
//原型模式的测试类
public class PrototypeTest
{
public static void main(String[] args)throws CloneNotSupportedException
{
Realizetype obj1=new Realizetype();
Realizetype obj2=(Realizetype)obj1.clone();
System.out.println("obj1==obj2?"+(obj1==obj2));
}
}
将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
定义一个用于创建产品的接口,由子类决定生产什么产品。
#产品类
abstract class BMW {
public BMW(){ }
}
public class BMW320 extends BMW {
public BMW320() {
System.out.println("制造-->BMW320");
}
}
public class BMW523 extends BMW{
public BMW523(){
System.out.println("制造-->BMW523");
}
}
#创建工厂类:
interface FactoryBMW {
BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW{
@Override
public BMW320 createBMW() {
return new BMW320();
}
}
public class FactoryBMW523 implements FactoryBMW {
@Override
public BMW523 createBMW() {
return new BMW523();
}
}
#客户类:
public class Customer {
public static void main(String[] args) {
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
BMW320 bmw320 = factoryBMW320.createBMW();
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
BMW523 bmw523 = factoryBMW523.createBMW();
}
}
提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
//发动机以及型号
public interface Engine {
}
public class EngineA extends Engine{
public EngineA(){
System.out.println("制造-->EngineA");
}
}
public class EngineBextends Engine{
public EngineB(){
System.out.println("制造-->EngineB");
}
}
//空调以及型号
public interface Aircondition {
}
public class AirconditionA extends Aircondition{
public AirconditionA(){
System.out.println("制造-->AirconditionA");
}
}
public class AirconditionB extends Aircondition{
public AirconditionB(){
System.out.println("制造-->AirconditionB");
}
}
//创建工厂
//创建工厂的接口
public interface AbstractFactory {
//制造发动机
public Engine createEngine();
//制造空调
public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements AbstractFactory{
@Override
public Engine createEngine() {
return new EngineA();
}
@Override
public Aircondition createAircondition() {
return new AirconditionA();
}
}
//宝马523系列
public class FactoryBMW523 implements AbstractFactory {
@Override
public Engine createEngine() {
return new EngineB();
}
@Override
public Aircondition createAircondition() {
return new AirconditionB();
}
}
//客户
public class Customer {
public static void main(String[] args){
//生产宝马320系列配件
FactoryBMW320 factoryBMW320 = new FactoryBMW320();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
//生产宝马523系列配件
FactoryBMW523 factoryBMW523 = new FactoryBMW523();
factoryBMW320.createEngine();
factoryBMW320.createAircondition();
}
}
将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建他们,最后构成该负责对象。
- 代理模式:
interface SayHello{
void sayHello(String name);
}
public class ProxyDemo implements SayHello {
public void sayHello(String name){
System.out.println("你好"+name);
}
public static void main(String[] args){
ProxyDemo proxyDemo = new ProxyDemo();
ProxyUtile proxyUtile = new ProxyUtile(proxyDemo);
SayHello instance = (SayHello) Proxy.newProxyInstance(ProxyDemo.class.getClassLoader(), new Class[]{SayHello.class}, proxyUtile);
instance.sayHello("飞翔的胖哥");
}
public static class ProxyUtile implements InvocationHandler{
private Object object;
public ProxyUtile(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(object,args);
}
}
}
由于某些原因,需要给某对象提供一个代理以控制对该对象的访问。
将抽象部分与它的实现部分分离,使他们可以独立的变化
//定义接口
public interface ElectricAppliance {
String description();
}
//具体实现
public class AirConditioner implements ElectricAppliance {
private final String name = "空调";
@Override
public String description() {
return name;
}
}
public class WashingMachine implements ElectricAppliance {
private final String name = "洗衣机";
@Override
public String description() {
return name;
}
}
public class WaterHeater implements ElectricAppliance {
private final String name = "热水器";
@Override
public String description() {
return name;
}
}
//定义桥接抽象类Brand
public abstract class Brand {
protected ElectricAppliance electricAppliance;
public Brand(ElectricAppliance electricAppliance) {
this.electricAppliance = electricAppliance;
}
abstract String description();
}
//抽象实现
public class Gree extends Brand {
private final String name = "格力";
public Gree(ElectricAppliance electricAppliance) {
super(electricAppliance);
}
@Override
public String description() {
return name + electricAppliance.description();
}
}
public class Haier extends Brand{
private final String name = "海尔";
public Haier(ElectricAppliance electricAppliance) {
super(electricAppliance);
}
@Override
public String description() {
return name + electricAppliance.description();
}
}
public class Midea extends Brand{
private final String name = "美的";
public Midea(ElectricAppliance electricAppliance) {
super(electricAppliance);
}
@Override
public String description() {
return name + electricAppliance.description();
}
}
//Test:测试类
ublic class Test {
public static void main(String[] args) {
Brand midea = new Midea(new WashingMachine());
System.out.println(midea.description());
Brand gree1 = new Gree(new WashingMachine());
System.out.println(gree1.description());
//添加新电器
Brand gree2 = new Gree(new AirConditioner());
System.out.println(gree2.description());
//添加新品牌
Brand haier1 = new Haier(new WashingMachine());
System.out.println(haier1.description());
Brand haier2 = new Haier(new WaterHeater());
System.out.println(haier2.description());
}
}
- 装饰模式:
- 外观模式:
- 享元模式:
一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。
//先定义一个抽象的Flyweight类
public abstract class Flyweight{
public abstract void operation();
}
//实现一个具体类:
public class ConcreteFlyweight extends Flyweight{
private String string;
public ConcreteFlyweight(String str){
string = str;
}
public void operation()
{
System.out.println("Concrete---Flyweight : " + string);
}
}
//实现一个工厂方法类:
public class FlyweightFactory{
private Hashtable flyweights = new Hashtable();//1、定义一个HashTable存储对象
public FlyweightFactory(){}
public Flyweight getFlyWeight(Object obj){
Flyweight flyweight = (Flyweight) flyweights.get(obj);//2、从HashTable获取对象
if(flyweight == null){//3、判断HashTbale是否存在该对象
//4、没有产生新的ConcreteFlyweight
flyweight = new ConcreteFlyweight((String)obj);
flyweights.put(obj, flyweight);//5、放入HashTable中
}
return flyweight;//6、将对象返回
}
public int getFlyweightSize(){
return flyweights.size();
}
}
//Flyweight的调用
public class FlyweightPattern{
FlyweightFactory factory = new FlyweightFactory();
Flyweight fly1;
Flyweight fly2;
Flyweight fly3;
Flyweight fly4;
Flyweight fly5;
Flyweight fly6;
/** *//** Creates a new instance of FlyweightPattern */
public FlyweightPattern(){
fly1 = factory.getFlyWeight("Google");
fly2 = factory.getFlyWeight("Qutr");
fly3 = factory.getFlyWeight("Google");
fly4 = factory.getFlyWeight("Google");
fly5 = factory.getFlyWeight("Google");
fly6 = factory.getFlyWeight("Google");
}
public void showFlyweight(){
fly1.operation();
fly2.operation();
fly3.operation();
fly4.operation();
fly5.operation();
fly6.operation();
int objSize = factory.getFlyweightSize();
System.out.println("objSize = " + objSize);
}
public static void main(String[] args){
System.out.println("The FlyWeight Pattern!");
FlyweightPattern fp = new FlyweightPattern();
fp.showFlyweight();
}
}
- 组合模式:
将对象组合成树形结构以表示“部分和整体”的层次结构。
我们有一个类 Employee,该类被当作组合模型类。CompositePatternDemo,我们的演示类使用 Employee 类来添加部门层次结构,并打印所有员工。
public class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates;
//构造函数
public Employee(String name,String dept, int sal) {
this.name = name;
this.dept = dept;
this.salary = sal;
subordinates = new ArrayList<Employee>();
}
public void add(Employee e) {
subordinates.add(e);
}
public void remove(Employee e) {
subordinates.remove(e);
}
public List<Employee> getSubordinates(){
return subordinates;
}
public String toString(){
return ("Employee :[ Name : "+ name
+", dept : "+ dept + ", salary :"
+ salary+" ]");
}
public static void main(String[] args){
Employee CEO = new Employee("John","CEO", 30000);
Employee headSales = new Employee("Robert","Head Sales", 20000);
Employee headMarketing = new Employee("Michel","Head Marketing", 20000);
Employee clerk1 = new Employee("Laura","Marketing", 10000);
Employee clerk2 = new Employee("Bob","Marketing", 10000);
Employee salesExecutive1 = new Employee("Richard","Sales", 10000);
Employee salesExecutive2 = new Employee("Rob","Sales", 10000);
CEO.add(headSales);
CEO.add(headMarketing);
headSales.add(salesExecutive1);
headSales.add(salesExecutive2);
headMarketing.add(clerk1);
headMarketing.add(clerk2);
//打印该组织的所有员工
System.out.println(CEO);
for (Employee headEmployee : CEO.getSubordinates()) {
System.out.println(headEmployee);
for (Employee employee : headEmployee.getSubordinates()) {
System.out.println(employee);
}
}
}
}
- 模板方法模式:
- 策略模式:
如果在一个系统里面有很多类,他们之间的区别仅在于他们的行为,那么使用策略模式可以动态的让一个对象选择一种行为
//抽象计算接口
public interface Strategy {
public int doOperation(int num1, int num2);
}
//加法实现
public class OperationAdd implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 + num2;
}
}
//减法实现
public class OperationSubtract implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 - num2;
}
}
//乘法实现
public class OperationMultiply implements Strategy{
@Override
public int doOperation(int num1, int num2) {
return num1 * num2;
}
}
//Context类
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
//启动类
public class StrategyPatternDemo {
public static void main(String[] args) {
Context context = new Context(new OperationAdd());
System.out.println("10 + 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationSubstract());
System.out.println("10 - 5 = " + context.executeStrategy(10, 5));
context = new Context(new OperationMultiply());
System.out.println("10 * 5 = " + context.executeStrategy(10, 5));
}
}
- 命令模式:
- 职责链模式:
- 状态模式:
- 观察者模式:
又称发布订阅模式,属于行为模式的一种,它定义了一种一对多的依赖关系
//让我们模拟一个明星发布新的动态后如何通知所有的粉丝
#粉丝抽象与实现
public interface Fan {
public void update(String message);
}
public class ConcreteFan implements Fan{
private String fanName;
public ConcreteFan(String fanName) {
this.fanName = fanName;
}
@Override
public void update(String message) {
System.out.println(fanName+"知道了:"+message);
}
}
#明星抽象与实现
public interface Idol {
//新增粉丝
public void addFan(Fan fan);
//删除粉丝
public void delete(Fan fan);
//通知动态
public void notify(String meaasge);
}
public class ConcreteIdol implements Idol {
private List<Fan> fanList = new ArrayList<>();
@Override
public void addFan(Fan fan) {
fanList.add(fan);
}
@Override
public void delete(Fan fan) {
fanList.remove(fan);
}
@Override
public void notify(String meaasge) {
for(Fan fan : fanList){
fan.update(meaasge);
}
}
}
#测试
public static void main(String[] args){
ConcreteIdol idol = new ConcreteIdol();
ConcreteFan fanA = new ConcreteFan("张三");
ConcreteFan fanB = new ConcreteFan("李四");
ConcreteFan fanC = new ConcreteFan("王五");
idol.addFan(fanA);
idol.addFan(fanB);
idol.addFan(fanC);
idol.notify("五一快乐!");
idol.delete(fanA);
idol.notify("五一快乐2!");
}
- 中介模式:
- 迭代器模式:
- 访问者模式:
- 备忘录模式:
- 解释器模式: