常用设计模式解析
Posted Smile_Miracle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用设计模式解析相关的知识,希望对你有一定的参考价值。
1 策略模式:分别封装行为接口,实现算法组,超类里面放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装为借口,基于接口编程各种功能。此模式让行为算法的变化独立于算法的使用者。
package com.mvs.mytest.superClasss;
import com.mvs.mytest.behavior.FlyBehavior;
import com.mvs.mytest.behavior.SwimBehavior;
public abstract class Duck
//分离变化部分为接口,让子类决定其具体变化
public FlyBehavior fb;
public SwimBehavior sb;
public Duck()
//构造函数让其子类构造函数可以定义行为
public void fly()
fb.fly();
public void swim()
sb.swim();
public abstract void display();
package com.mvs.mytest.behavior;
public interface FlyBehavior
public void fly();
package com.mvs.mytest.behavior;
public interface SwimBehavior
public void swim();
package com.mvs.mytest.behavior;
public class GoodFlyBehavior implements FlyBehavior
@Override
public void fly()
System.out.println("I CAN FLY");
package com.mvs.mytest.behavior;
public class BadFlyBehavior implements FlyBehavior
@Override
public void fly()
System.out.println("I CAN NOT FLY");
package com.mvs.mytest.behavior;
public class GoodSwimBehavior implements SwimBehavior
@Override
public void swim()
System.out.println("I CAN SWIM");
package com.mvs.mytest.behavior;
public class BadSwimBehavior implements SwimBehavior
@Override
public void swim()
System.out.println("I CAN NOT SWIM");
package com.mvs.mytest.Test;
import com.mvs.mytest.behavior.GoodFlyBehavior;
import com.mvs.mytest.behavior.GoodSwimBehavior;
import com.mvs.mytest.superClasss.Duck;
public class GreenDuck extends Duck
@Override
public void display()
System.out.println("GREEN DUCK");
public GreenDuck()
this.fb = new GoodFlyBehavior();
this.sb=new GoodSwimBehavior();
package com.mvs.mytest.Test;
import com.mvs.mytest.behavior.BadFlyBehavior;
import com.mvs.mytest.behavior.BadSwimBehavior;
import com.mvs.mytest.superClasss.Duck;
public class RedDuck extends Duck
@Override
public void display()
System.out.println("RED DUCK");
public RedDuck()
this.fb = new BadFlyBehavior();
this.sb=new BadSwimBehavior();
package com.mvs.mytest.Test;
public class MyTest
public static void main(String[] args)
GreenDuck gd = new GreenDuck();
gd.fly();
gd.swim();
gd.display();
RedDuck rd = new RedDuck();
rd.fly();
rd.swim();
rd.display();
2 观察者模式:在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。
package com.mvs.mytest.superClasss;
import java.util.ArrayList;
import java.util.List;
import com.mvs.mytest.model.TestModel;
public class Subject
public List<Observer> observers;
observers = new ArrayList<Observer>();
public void registObserver(Observer o)
observers.add(o);
public void removeObserver(Observer o)
if(observers.contains(o))
observers.remove(o);
public void notifyObservers(TestModel model)
if(model.getFlag())
for (Observer observer : observers)
observer.update(model);
public boolean hasChanged(boolean flag)
return flag;
package com.mvs.mytest.superClasss;
import com.mvs.mytest.model.TestModel;
public interface Observer
public void update(TestModel model);
package com.mvs.mytest.behavior;
import com.mvs.mytest.model.TestModel;
import com.mvs.mytest.superClasss.Subject;
public class CoreBehavior extends Subject
private TestModel model;
public TestModel getModel()
return model;
public CoreBehavior( TestModel model)
this.model = model;
public void sendNotice()
this.notifyObservers(getModel());
package com.mvs.mytest.behavior;
import com.mvs.mytest.model.TestModel;
import com.mvs.mytest.superClasss.Observer;
public class FirstObserver implements Observer
@Override
public void update(TestModel model)
System.out.println("*****The First Observer: AAA"+model.getfStr()+"*****");
System.out.println("*****The First Observer: AAA"+model.getsStr()+"*****");
System.out.println("*****The First Observer: AAA"+model.gettStr()+"*****");
package com.mvs.mytest.behavior;
import com.mvs.mytest.model.TestModel;
import com.mvs.mytest.superClasss.Observer;
public class SecondObserver implements Observer
@Override
public void update(TestModel model)
System.out.println("*****The Second Observer: BBB"+model.getfStr()+"*****");
System.out.println("*****The Second Observer: BBB"+model.getsStr()+"*****");
System.out.println("*****The Second Observer: BBB"+model.gettStr()+"*****");
package com.mvs.mytest.model;
public class TestModel
public String fStr;
public String sStr;
public String tStr;
private Boolean flag;
public Boolean getFlag()
return flag;
public void setFlag(Boolean flag)
this.flag = flag;
public String getfStr()
return fStr;
public void setfStr(String fStr)
this.fStr = fStr;
public String getsStr()
return sStr;
public void setsStr(String sStr)
this.sStr = sStr;
public String gettStr()
return tStr;
public void settStr(String tStr)
this.tStr = tStr;
package com.mvs.mytest.Test;
import com.mvs.mytest.behavior.CoreBehavior;
import com.mvs.mytest.behavior.FirstObserver;
import com.mvs.mytest.behavior.SecondObserver;
import com.mvs.mytest.model.TestModel;
public class Test
public static void main(String[] args)
//消费者
FirstObserver fo = new FirstObserver();
SecondObserver so = new SecondObserver();
TestModel model = new TestModel();
model.setfStr("111");
model.setsStr("222");
model.settStr("333");
model.setFlag(true);
//生产者
CoreBehavior cb = new CoreBehavior(model);
//注册服务
cb.registObserver(fo);
cb.registObserver(so);
//发送通知
cb.sendNotice();
System.out.println("---------------------分割线-------------------");
//测试删除
cb.removeObserver(so);
cb.sendNotice();
3 装饰者模式:对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮、更温馨、更实用。在软件设计中,对已有对象(新房)的功能进行扩展装修)。把通用功能封装在装饰器中,用到的地方进行调用。装饰模式是一种用于替代继承的技术,使用对象之间的关联关系取代类之间的继承关系。装饰者模式要适用于有依赖关系的场景,装饰者必须要依赖被装饰者而存在,例如点餐场景中辣微辣,加不加葱都是配料依赖主菜的形式
package com.mvs.mytest.superClasss;
public abstract class Drink
public String description="";
public float price=0f;
public String demand;
public String getDemand()
return demand;
public void setDemand(String demand)
this.demand = demand;
public String getDescription()
return description+""+this.getPrice();
public void setDescription(String description)
this.description = description;
public float getPrice()
return price;
public void setPrice(float price)
this.price = price;
public abstract float cost();
package com.mvs.mytest.coffeeType;
import com.mvs.mytest.superClasss.Drink;
public abstract class Coffee extends Drink
@Override
public float cost()
return this.getPrice();
package com.mvs.mytest.coffeeType;
public class Decaf extends Coffee
public Decaf()
this.setDescription("Decaf");
this.setPrice(5.6f);
package com.mvs.mytest.coffeeType;
public class LongBlack extends Coffee
public LongBlack()
this.setDescription("LongBlack");
this.setPrice(8.8f);
package com.mvs.mytest.coffeeType;
public class Morca extends Coffee
public Morca()
this.setDescription("Morca");
this.setPrice(12.9f);
package com.mvs.mytest.flavoring;
import org.apache.commons.lang3.StringUtils;
import com.mvs.mytest.superClasss.Drink;
//装饰者模式要适用于有依赖关系的场景,装饰者必须要依赖被装饰者而存在,例如点餐场景中辣微辣,加不加葱都是配料依赖主菜的形式
public class Decorator extends Drink
private Drink obj;
public Decorator(Drink obj)
this.obj = obj;
@Override
public float cost()
return super.getPrice()+obj.cost();//一层层包装,然后递归获取计算后的总价
@Override
public String getDescription()
return super.description+"-"+super.getPrice()+"&&"+obj.getDescription();//重写描述递归列出详情
@Override
public String getDemand()
String str = "";
if(StringUtils.isNotBlank(obj.getDemand()))
str = super.description+"-"+super.getDemand()+"&&"+obj.getDemand();//重写描述递归列出详情
else
str = super.description+"-"+super.getDemand();
return str;
package com.mvs.mytest.flavoring;
import com.mvs.mytest.superClasss.Drink;
public class Chocolate extends Decorator
public Chocolate(Drink obj,String demand)
super(obj);
this.setDescription("Chocolate");
this.setPrice(5.0f);
this.setDemand(demand);
package com.mvs.mytest.flavoring;
import com.mvs.mytest.superClasss.Drink;
public class Milk extends Decorator
public Milk(Drink obj,String demand)
super(obj);
this.setDescription("Milk");
this.setPrice(3.0f);
this.setDemand(demand);
package com.mvs.mytest.flavoring;
import com.mvs.mytest.superClasss.Drink;
public class Suger extends Decorator
public Suger(Drink obj,String demand)
super(obj);
this.setDescription("Suger");
this.setPrice(0f);
this.setDemand(demand);
package com.mvs.mytest.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.mvs.mytest.coffeeType.Decaf;
import com.mvs.mytest.flavoring.Chocolate;
import com.mvs.mytest.flavoring.Milk;
import com.mvs.mytest.flavoring.Suger;
import com.mvs.mytest.superClasss.Drink;
public class MyTest
public static void main(String[] args)
Drink de = new Decaf();
de = new Chocolate(de,"");
de = new Milk(de,"多放点牛奶");
de = new Suger(de,"半塘");
System.out.println(de.getDescription());
System.out.println(de.cost());
String demand = de.getDemand();
List<String> asList = new ArrayList<>(Arrays.asList(demand.split("&&")));
Iterator<String> iterator = asList.iterator();
while(iterator.hasNext())
if(iterator.next().split("-").length!=2)
iterator.remove();
System.out.println(asList.toString());
4 单例模式: 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计
package com.mvs.mytest.Test;
/**
* 饿汉式
* @author zhonghy
*
*/
public class HungerModel
private static HungerModel instance = new HungerModel();
private HungerModel()
public static HungerModel getInstance()
return instance;
package com.mvs.mytest.Test;
/**
* 懒汉式
* @author zhonghy
*
*/
public class SlackerModel
private static SlackerModel instance;
private SlackerModel()
public synchronized static SlackerModel getInstance()
if(instance==null)
instance = new SlackerModel();
return instance;
package com.mvs.mytest.Test;
/**
* 静态内部类模式
* @author zhonghy
* 使用内部类的好处是,静态内部类不会在单例加载时就加载,而是在调用getInstance()方法时才进行加载,达到了类似懒汉模式的效果,而这种方法又是线程安全的
*
*/
public class StaticModel
private static class StaticHolder
private static StaticModel instance=new StaticModel();
private StaticModel()
public static StaticModel getInstance()
return StaticHolder.instance;
5 工厂模式: 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部大机器中的一个齿轮传动。工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。主要分为简单工厂模式,抽象工厂模式以及工厂方法模式。
简单工厂模式: 定义一个创建对象的类,由这个类来封装实例化对象的行为
工厂方法模式: 定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到 子类
抽象工程模式: 定义了一个接口用于创建相关或者有依赖关系的对象族,而无需明确指定具体类
package com.mvs.mytest.superClasss;
public abstract class Pizza
protected String name;
public Pizza(String name)
this.name = name;
public abstract void prepare();
public void bake()
System.out.println(name+"-Baking");
public void cut()
System.out.println(name+"-Cutting");
public void box()
System.out.println(name+"-Boxing");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class AMCheesePizza extends Pizza
public AMCheesePizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Cheese From AME");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class AMDurianPizza extends Pizza
public AMDurianPizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Seafood From AME");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class AMSeafoodPizza extends Pizza
public AMSeafoodPizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Seafood From AME");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class CHNCheesePizza extends Pizza
public CHNCheesePizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Cheese From CHN");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class CHNDurianPizza extends Pizza
public CHNDurianPizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Durian From CHN");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
public class CHNSeafoodPizza extends Pizza
public CHNSeafoodPizza(String name)
super(name);
@Override
public void prepare()
System.out.println("We Need Seafood From CHN");
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Pizza;
/**
* 简单工厂模式:定义一个创建对象的类,由这个类来封装实例化对象的行为
* @author zhonghy
*
*/
public class SimplePizzaFactory
public Pizza getInstance(String type)
Pizza pizza = null;
if(type.equals("cheese"))
pizza = new CHNCheesePizza(type);
else if(type.equals("seafood"))
pizza = new CHNSeafoodPizza(type);
else if(type.equals("durian"))
pizza = new CHNDurianPizza(type);
else
System.out.println("No Such Kind Of Pizza!!!");
return pizza;
package com.mvs.mytest.expandAction;
import com.mvs.mytest.baseAction.AMCheesePizza;
import com.mvs.mytest.baseAction.AMDurianPizza;
import com.mvs.mytest.baseAction.AMSeafoodPizza;
import com.mvs.mytest.superClasss.Pizza;
public class AbsAmPizzaFactory implements AbsPizzaPactory
@Override
public Pizza getInstance(String type)
Pizza pizza = null;
if(type.equals("cheese"))
pizza = new AMCheesePizza(type);
else if(type.equals("seafood"))
pizza = new AMSeafoodPizza(type);
else if(type.equals("durian"))
pizza = new AMDurianPizza(type);
else
System.out.println("No Such Kind Of Pizza!!!");
return pizza;
package com.mvs.mytest.expandAction;
import com.mvs.mytest.baseAction.CHNCheesePizza;
import com.mvs.mytest.baseAction.CHNDurianPizza;
import com.mvs.mytest.baseAction.CHNSeafoodPizza;
import com.mvs.mytest.superClasss.Pizza;
public class AbsChnPizzaFactory implements AbsPizzaPactory
@Override
public Pizza getInstance(String type)
Pizza pizza = null;
if(type.equals("cheese"))
pizza = new CHNCheesePizza(type);
else if(type.equals("seafood"))
pizza = new CHNSeafoodPizza(type);
else if(type.equals("durian"))
pizza = new CHNDurianPizza(type);
else
System.out.println("No Such Kind Of Pizza!!!");
return pizza;
package com.mvs.mytest.expandAction;
import com.mvs.mytest.superClasss.Pizza;
public interface AbsPizzaPactory
public Pizza getInstance(String type);
package com.mvs.mytest.Test;
import com.mvs.mytest.expandAction.AbsPizzaPactory;
import com.mvs.mytest.superClasss.Pizza;
public class AbsOrderPizza
public AbsPizzaPactory pizzaFactory;
public AbsOrderPizza(AbsPizzaPactory pizzaFactory,String type)
setFactory(pizzaFactory,type);
private void setFactory(AbsPizzaPactory pizzaFactory,String type)
this.pizzaFactory = pizzaFactory;
Pizza pizza = pizzaFactory.getInstance(type);
if(pizza!=null)
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
package com.mvs.mytest.Test;
import com.mvs.mytest.baseAction.AMCheesePizza;
import com.mvs.mytest.baseAction.AMDurianPizza;
import com.mvs.mytest.baseAction.AMSeafoodPizza;
import com.mvs.mytest.superClasss.Pizza;
public class AMEOrderPizza extends MethodOrderPizza
public AMEOrderPizza(String type)
super(type);
@Override
public Pizza getInstance(String type)
Pizza pizza = null;
if(type.equals("cheese"))
pizza = new AMCheesePizza(type);
else if(type.equals("seafood"))
pizza = new AMSeafoodPizza(type);
else if(type.equals("durian"))
pizza = new AMDurianPizza(type);
else
System.out.println("No Such Kind Of Pizza!!!");
return pizza;
package com.mvs.mytest.Test;
import com.mvs.mytest.baseAction.CHNCheesePizza;
import com.mvs.mytest.baseAction.CHNDurianPizza;
import com.mvs.mytest.baseAction.CHNSeafoodPizza;
import com.mvs.mytest.superClasss.Pizza;
public class CHNOrderPizza extends MethodOrderPizza
public CHNOrderPizza(String type)
super(type);
@Override
public Pizza getInstance(String type)
Pizza pizza = null;
if(type.equals("cheese"))
pizza = new CHNCheesePizza(type);
else if(type.equals("seafood"))
pizza = new CHNSeafoodPizza(type);
else if(type.equals("durian"))
pizza = new CHNDurianPizza(type);
else
System.out.println("No Such Kind Of Pizza!!!");
return pizza;
package com.mvs.mytest.Test;
import com.mvs.mytest.superClasss.Pizza;
public abstract class MethodOrderPizza
public MethodOrderPizza(String type)
Pizza pizza = getInstance(type);
if(pizza!= null)
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
public abstract Pizza getInstance(String type);
package com.mvs.mytest.Test;
import com.mvs.mytest.baseAction.SimplePizzaFactory;
import com.mvs.mytest.superClasss.Pizza;
public class OrderPizza
public SimplePizzaFactory pizzaFactory;
public void order(SimplePizzaFactory pizzaFactory,String type)
setFactory(pizzaFactory,type);
private void setFactory(SimplePizzaFactory pizzaFactory, String type)
this.pizzaFactory = pizzaFactory;
Pizza pizza = pizzaFactory.getInstance(type);
if(pizza!= null)
pizza.prepare();
pizza.bake();
pizza.cut();
pizza.box();
package com.mvs.mytest.Test;
import com.mvs.mytest.baseAction.SimplePizzaFactory;
import com.mvs.mytest.expandAction.AbsAmPizzaFactory;
public class MyTest
@SuppressWarnings("unused")
public static void main(String[] args)
//简单工厂模式
OrderPizza o = new OrderPizza();
o.order(new SimplePizzaFactory(), "seafood");
System.out.println("****************************************");
//工厂方法模式
MethodOrderPizza mo = new CHNOrderPizza("durian");
System.out.println("****************************************");
//抽象工厂模式
AbsOrderPizza ao = new AbsOrderPizza(new AbsAmPizzaFactory(), "cheese");
6 适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作(常用为转化两套实现体系中的方法为通用)
package com.mvs.mytest.superClasss;
public interface Duck
public void quack();
public void fly();
package com.mvs.mytest.baseAction;
import com.mvs.mytest.superClasss.Duck;
public class RedDuck implements Duck
@Override
public void quack()
System.out.println("鸭子叫");
@Override
public void fly()
System.out.println("鸭子飞");
package com.mvs.mytest.superClasss;
public interface Turkey
public void shouts();
public void jump();
package com.mvs.mytest.expandAction;
import com.mvs.mytest.superClasss.Turkey;
public class BigTurkey implements Turkey
@Override
public void shouts()
System.out.println("火鸡叫");
@Override
public void jump()
System.out.println("火鸡跳");
package com.mvs.mytest.superClasss;
//以要被适配的超类接口实现适配,适配器还分类适配与对象适配
//由于JAVA单继承的关系,建议多用对象适配,你也可以抽象这个对象,让他的子类来适配
public class DuckAdapter implements Duck
private Turkey tt;
public DuckAdapter(Turkey tt)
super();
this.tt = tt;
@Override
public void quack()
tt.shouts();
@Override
public void fly()
tt.jump();
package com.mvs.mytest.Test;
import com.mvs.mytest.baseAction.RedDuck;
import com.mvs.mytest.expandAction.BigTurkey;
import com.mvs.mytest.superClasss.Duck;
import com.mvs.mytest.superClasss.DuckAdapter;
public class MyTest
public static void main(String[] args)
Duck duck = new RedDuck();
duck.quack();
duck.fly();
System.out.println("******************************************");
duck = new DuckAdapter(new BigTurkey());
duck.quack();
duck.fly();
以上是关于常用设计模式解析的主要内容,如果未能解决你的问题,请参考以下文章
深入理解JavaScript系列(39):设计模式之适配器模式
火鸡堂 对 基于云的胜利冲锋队 为了交项目干杯 的 Beta 产品测试报告