为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
1.当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越 复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容 易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。 Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需 要更多的可定制性的用户可以越过facade层。
2.客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade将这个子系统与客 户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
3.当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。 如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们 之间的依赖关系。
例子:
外观类:
public class Facade {
ServiceA sa;
ServiceB sb;
ServiceC sc;
public Facade() {
sa = new ServiceAImpl();
sb = new ServiceBImpl();
sc = new ServiceCImpl();
}
public void methodA() {
sa.methodA();
sb.methodB();
}
public void methodB() {
sb.methodB();
sc.methodC();
}
public void methodC() {
sc.methodC();
sa.methodA();
}
}
接口和接口的实现类:
public interface ServiceA {
void methodA() ;
}
public class ServiceAImpl implements ServiceA{
@Override
public void methodA() {
System.out.println("这是服务A");
}
}
public interface ServiceB {
void methodB() ;
}
public class ServiceBImpl implements ServiceB{
@Override
public void methodB() {
System.out.println("这是服务B");
}
}
public interface ServiceC {
void methodC() ;
}
public class ServiceCImpl implements ServiceC{
@Override
public void methodC() {
System.out.println("这是服务C");
}
}
测试类:
public class Test {
public static void main(String[] args) {
ServiceA sa = new ServiceAImpl();
ServiceB sb = new ServiceBImpl();
sa.methodA();
sb.methodB();
System.out.println("========");
//facade
Facade facade = new Facade();
facade.methodA();
facade.methodB();
facade.methodC();
}
}
运用共享技术有效地支持大量细粒度的对象。
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。 首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。 最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3.控制子类扩展。
例子;
享元接口:
public interface Flyweight {
void action(int arg);
}
享元接口的实现类:
public class FlyweightImpl implements Flyweight{
@Override
public void action(int arg) {
System.out.println("参数值: " + arg);
}
}
产生精度对象的工厂类:
public class FlyweightFactory {
private static Map<String,Flyweight> flyweightsMap = new HashMap<String,Flyweight>();
public FlyweightFactory(String arg) {
System.out.println("-----------------");
flyweightsMap.put(arg, new FlyweightImpl());
}
public static Flyweight getFlyweight(String key) {
if (flyweightsMap.get(key) == null) {
flyweightsMap.put(key, new FlyweightImpl());
}
return (Flyweight) flyweightsMap.get(key);
}
public static int getSize() {
return flyweightsMap.size();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Flyweight fly1 = FlyweightFactory.getFlyweight("a");
fly1.action(1);
Flyweight fly2 = FlyweightFactory.getFlyweight("a");
System.out.println(fly1 == fly2);
Flyweight fly3 = FlyweightFactory.getFlyweight("c");
fly3.action(3);
Flyweight fly4 = FlyweightFactory.getFlyweight("d");
fly4.action(4);
Flyweight fly5 = FlyweightFactory.getFlyweight("e");
fly5.action(5);
System.out.println(FlyweightFactory.getSize());
}
}
代理模式实现了类与类之间直接调用的解耦,例子:
代理模式主要使用了java的多态,干活的是被代理类,代理类主要的接活
,把活交给幕后的被代理类做,代理类和被代理类实现同一个接口。
被代理类的接口:
public interface Object {
void action();
}
被代理类的接口实现类:
public class ObjectImpl implements Object{
public void action() {
System.out.println("========");
System.out.println("========");
System.out.println("这是被代理的类");
System.out.println("========");
System.out.println("========");
}
}
代理类:
public class ProxyObject implements Object{
Object obj;
public ProxyObject() {
System.out.println("这是代理类");
obj = new ObjectImpl();
}
public void action() {
System.out.println("代理开始");
obj.action();
System.out.println("代理结束");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Object obj = new ProxyObject();
obj.action();
}
}
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
适合场合:
* 1.以不同的格式保存文件
* 2.以不同的算法压缩文件
* 3.以不同的算法截取图形
* 4.以不同的格式输出数据的图形,曲线,框图等
策略接口:
public interface Strategy {
void method();
}
策略接口实现类:
public class StrategyImplA implements Strategy{
public void method() {
System.out.println("这是第一个实现a");
}
}
public class StrategyImplB implements Strategy{
public void method() {
System.out.println("这是第二个实现b");
}
}
public class StrategyImplC implements Strategy{
public void method() {
System.out.println("这是第三个实现c");
}
}
调用类:
public class Context {
Strategy stra;
public Context(Strategy stra) {
this.stra = stra;
}
public void doMethod() {
stra.method();
}
}
测试:
public class Test {
public static void main(String[] args) {
Context ctx = new Context(new StrategyImplA());
ctx.doMethod();
ctx = new Context(new StrategyImplB());
ctx.doMethod();
ctx = new Context(new StrategyImplC());
ctx.doMethod();
}
}
命令模式就是将一组对象的相似行为,进行了抽象,将调用者与被调用者之间进行解耦,提
高了应用的灵活性。命令模式将调用的目标对象的一些异构性给封装起来,通过统一的方式来为调用者提供服务。
适用场景
1、当一个应用程序调用者与多个目标对象之间存在调用关系时,并且目标对象之间的操作很类似的时候。
2、例如当一个目标对象内部的方法调用太复杂,或者内部的方法需要协作才能完成对象的某个特点操作时。
3、有时候调用者调用目标对象后,需要回调一些方法。
例子:
命令接口:
public interface Commond {
public void execute();
}
命令接口实现类:
public class LightOnCommond implements Commond{
private Light light;
public LightOnCommond(Light light) {
this.light = light;
}
@Override
public void execute() {
light.on();
}
}
命令的调用者:
public class Light {
public void on() {
System.out.println("灯亮了");
}
}
public class TurnTvCommond implements Commond {
private Tv tv;
public TurnTvCommond(Tv tv) {
this.tv = tv;
}
@Override
public void execute() {
tv.turn();
}
}
public class Tv {
public void turn() {
System.out.println("调台");
}
}
同时执行的多个命令数组
public class MracoCommond implements Commond{
private Commond[] commonds;
public MracoCommond(Commond...commonds) {
this.commonds = commonds;
}
@Override
public void execute() {
for(Commond cmd : commonds) {
cmd.execute();
}
}
}
命令的包装类,
public class RemoteContro {
private List<Commond> commondList = new ArrayList<Commond>();
public void setCommond(Commond commond) {
commondList.add(commond);
}
public void buttonWasPressed(int index){
commondList.get(index-1).execute();
}
}
public class Test {
public static void main(String[] args) {
Light light = new Light();
LightOnCommond loc = new LightOnCommond(light);
Tv tv = new Tv();
TurnTvCommond ttc = new TurnTvCommond(tv);
MracoCommond mc = new MracoCommond(loc,ttc);
RemoteContro rc = new RemoteContro();
rc.setCommond(ttc);
rc.setCommond(loc);
rc.setCommond(mc);
//rc.buttonWasPressed(3);
//rc.buttonWasPressed(1);
rc.buttonWasPressed(2);
}
}
当输入123不同时,调用的命令不同,实现了多个命令的包装
1.把依赖类(Service)和被依赖类(Dao)全部交给Spring管理
2.依赖类中提供被依赖类的set方法
3.在xml中进行配置
当把一个类交给spring管理是要给出一个无参数的构造方法给spring使用
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1" scope="prototype">
</bean>
scope="prototype"是创建多例,不配置此项,默认单例
或者lazy-init值设置为true
public class Person1 implements Person{
private Person1(String s){
System.out.println(s);
}
public void say() {
System.out.println("00000000000000");
}
public static Person1 getPerson1(){
return new Person1("pppppppppp");
}
}
<bean id="person" class="com.yjw.bean.Person1" factory-method="getPerson1">
public class Test {
public static void main(String[] args) {
ApplicationContext ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
// UserService userservice =(UserService) ctx.getBean("person");
/* User u = new User();
u.setUsername("qq");
u.setPassword("qq");
userservice.save(u);*/
Person person = (Person) ctx.getBean("person");
person.say();
}
}
概述:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
适用性:
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。 3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。
我们以天气预报的服务为例,安卓和诺基亚购买天气预报的服务,也可以停用服务:
天气预报主体的接口:
public interface Subject {
public void zhuce(Observer observer);
public void remove(Observer observer);
public void tongzhi();
}
天气预报的实现类:
public class WeatherData implements Subject {
private int low;
private int hight;
private String weather;
private List<Observer> list = new ArrayList<Observer>();
public void setData(int low, int hight, String weather) {
this.low = low;
this.hight = hight;
this.weather = weather;
tongzhi();
}
public int getLow() {
return low;
}
public int getHight() {
return hight;
}
public String getWeather() {
return weather;
}
public void zhuce(Observer observer) {
if (!list.contains(observer)) {
list.add(observer);
}
}
public void remove(Observer observer) {
if (list.contains(observer)) {
list.remove(observer);
}
}
public void tongzhi() {
for (Observer o : list) {
o.update(getLow(), getHight(), getWeather());
}
}
}
观察者的接口:
public interface Observer {
void remove();
void update(int low, int hight, String weather);
}
观察者的实现类:
public class Android implements Observer {
private Subject subject;
public Android() {
}
public Android(Subject subject) {
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("android" + low + "" + hight + weather);
}
public void remove() {
subject.remove(this);
}
}
public class Nokia implements Observer{
private Subject subject;
public Nokia(){}
public Nokia(Subject subject){
this.subject = subject;
this.subject.zhuce(this);
}
public void update(int low, int hight, String weather) {
System.out.println("nokia:"+low+"-"+hight+"-"+weather);
}
public void remove(){
subject.remove(this);
}
}
测试类:
public class Test {
public static void main(String[] args) {
WeatherData wd = new WeatherData();
wd.setData(1, 22, "晴朗");
Android a = new Android(wd);
wd.tongzhi();
a.remove();
Nokia n = new Nokia(wd);
n.remove();
wd.tongzhi();
}
}
状态模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
用性:1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。
通常,有多个操作包含这一相同的条件结构。
State模式将每一个条件分支放入一个独立的类中。
这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
状态模式在工作流或游戏等各种系统中有大量使用,甚至是这些系统的核心功能设计,例如
政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等
各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状
态的使用者。
在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各种状态,使用状态模式就
可以实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游
戏架构功能实现起到决定的主导作用。
状态模式实质:
使用状态模式前,客户端外界需要介入改变状态,而状态改变的实现是琐碎或复杂的。
使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如
何状态变化,这些是由状态机等内部实现。
这是一种Event-condition-State,状态模式封装了condition-State部分。
每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换
的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。
状态转换有几个方法实现:一个在每个状态实现next(),指定下一个状态;还有一种方法,
设定一个StateOwner,在StateOwner设定stateEnter状态进入和stateExit状
态退出行为。
状态从一个方面说明了流程,流程是随时间而改变,状态是截取流程某个时间片。
例子:
操作当前状态类:
public class Context {
private Weather weather;
public void setWeather(Weather weather) {
this.weather = weather;
}
public Weather getWeather() {
return this.weather;
}
public String weatherMessage() {
return weather.getWeather();
}
}
状态接口:
public interface Weather {
String getWeather();
}
状态实现类:
public class Sunshine implements Weather{
public String getWeather() {
return "阳光";
}
}
public class Rain implements Weather{
public String getWeather() {
return "下雨";
}
}
测试类:
public class Test {
public static void main(String[] args) {
Context ctx1 = new Context();
ctx1.setWeather(new Sunshine());
System.out.println(ctx1.weatherMessage());
System.out.println("===============");
ctx1.setWeather(new Rain());
System.out.println(ctx1.weatherMessage());
}
}
例子2:
public class Work {
private State current;
public Work(double hour,boolean finish){
current = new ForenoonState();
this.hour = hour;
this.finish = finish;
}
private double hour;
public double getHour() {
return hour;
}
public State getCurrent() {
return current;
}
public void setCurrent(State current) {
this.current = current;
}
private boolean finish;
public boolean isFinish() {
return finish;
}
public void writeProgram(){
current.writeProgram(this);
}
}
public interface State {
void writeProgram(Work work);
}
public class ForenoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<12){
System.out.println("工作时间");
}else {
work.setCurrent(new NoonState());
work.writeProgram();
}
}
}
public class NoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<13){
System.out.println("午睡");
}else {
work.setCurrent(new AfterNoonState());
work.writeProgram();
}
}
}
public class AfterNoonState implements State {
@Override
public void writeProgram(Work work) {
if(work.getHour()<17){
System.out.println("工作");
}else {
work.setCurrent(new EveningState());
work.writeProgram();
}
}
}
public class EveningState implements State {
@Override
public void writeProgram(Work work) {
if(work.isFinish()){
work.setCurrent(new RestState());
work.writeProgram();
}else {
if(work.getHour()<21){
System.out.println("加班");
}else {
work.setCurrent(new SleepState());
work.writeProgram();
}
}
}
}
public class SleepState implements State {
@Override
public void writeProgram(Work work) {
System.out.println("睡觉");
}
}