设计模式——java
设计模式;
一个程序员对设计模式的理解:
“不懂”为什么要把很简单的东西搞得那么复杂。后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式,目的仅仅是着眼于解决现在的问题,而设计模式的“复杂”就在于它是要构造一个“万能钥匙”,目的是提出一种对所有锁的开锁方案。在真正理解设计模式之前我一直在编写“简单”的代码.
这个“简单”不是功能的简单,而是设计的简单。简单的设计意味着缺少灵活性,代码很钢硬,只在这个项目里有用,拿到其它的项目中就是垃圾,我将其称之为“一次性代码”。
1.
逻辑代码独立到单独的方法中,注重封装性--易读,易复用。
不要在一个方法中,写下上百行的逻辑代码。把各小逻辑代码独立出来,写于其它方法中,易读其可重复调用。
2.
写类,写方法,写功能时,应考虑其移植性,复用性:防止一次性代码!
是否可以拿到其它同类事物中应该?是否可以拿到其它系统中应该?
3.
熟练运用继承的思想:
找出应用中相同之处,且不容易发生变化的东西,把它们抽取到抽象类中,让子类去继承它们;
继承的思想,也方便将自己的逻辑建立于别人的成果之上。如ImageField extends JTextField;
熟练运用接口的思想:
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
说明:
模拟鸭子游戏的应用程序,要求:游戏中会出现各种颜色外形的鸭子,一边游泳戏水,一边呱呱叫。
直接编写出各种鸭子的类:MallardDuck//野鸭,RedheadDuck//红头鸭,各类有三个方法:
quack():叫的方法
swim():游水的方法
display():外形的方法
即:设计一个鸭子的超类(Superclass),并让各种鸭子继承这个超类。
public class Duck{
public void quack(){ //呱呱叫
System.out.println("呱呱叫");
}
public void swim(){ //游泳
System.out.println(" 游泳");
}
public abstratact void display(); /*因为外观不一样,让子类自己去决定了。*/
}
//野鸭
public class MallardDuck extends Duck{
public void display(){
System.out.println("野鸭的颜色...");
}
}
//红头鸭
public class RedheadDuck extends Duck{
public void display(){
System.out.println("红头鸭的颜色...");
}
}
public class Duck{
public void quack(){ //呱呱叫
System.out.println("呱呱叫");
}
public void swim(){ //游泳
System.out.println(" 游泳");
}
public abstract void display(); /*因为外观不一样,让子类自己去决定了。*/
public void fly(){
System.out.println("飞吧!鸭子");
}
}
对于不能飞的鸭子,在子类中只需简单的覆盖。
//残废鸭
public class DisabledDuck extends Duck{
public void display(){
System.out.println("残废鸭的颜色...");
}
public void fly(){
//覆盖,变成什么事都不做。
}
}
其它会飞的鸭子不用覆盖。
对于上面的设计,你可能发现一些弊端,如果超类有新的特性,子类都必须变动,这是我们开发最不喜欢看到的,一个类变让另一个类也跟着变,这有点不符合OO设计了。这样很显然的耦合了一起。利用继承-->耦合度太高了.
用接口改进.
我们把容易引起变化的部分提取出来并封装之,来应付以后的变法。虽然代码量加大了,但可用性提高了,耦合度也降低了。
public interface Flyable{
public void fly();
}
public interface Quackable{
public void quack();
}
最后Duck的设计成为:
public class Duck{
public void swim(){ //游泳
System.out.println(" 游泳");
}
public abstract void display(); /*因为外观不一样,让子类自 己去决定了。*/
}
而MallardDuck,RedheadDuck,DisabledDuck 就可以写成为:
//野鸭
public class MallardDuck extends Duck implements Flyable,Quackable{
public void display(){
System.out.println("野鸭的颜色...");
}
public void fly(){
//实现该方法
}
public void quack(){
//实现该方法
}
}
//红头鸭
public class RedheadDuck extends Duck implements Flyable,Quackable{
public void display(){
System.out.println("红头鸭的颜色...");
}
public void fly(){
//实现该方法
}
public void quack(){
//实现该方法
}
}
//残废鸭 只实现Quackable(能叫不能飞)
public class DisabledDuck extends Duck implements Quackable{
public void display(){
System.out.println("残废鸭的颜色...");
}
public void quack(){
//实现该方法
}
}
好处:
这样已设计,我们的程序就降低了它们之间的耦合。
不足:
Flyable和 Quackable接口一开始似乎还挺不错的,解决了问题(只有会飞到鸭子才实现 Flyable),但是Java接口不具有实现代码,所以实现接口无法达到代码的复用。
继承的好处:让共同部分,可以复用.避免重复编程.
我们有一个设计原则:
找出应用中相同之处,且不容易发生变化的东西,把它们抽取到抽象类中,让子类去继承它们;
找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。 -->important.
public interface FlyBehavior{
public void fly();
}
public interface QuackBehavior{
public void quack();
}
我们在定义一些针对FlyBehavior的具体实现。
public class FlyWithWings implements FlyBehavior{
public void fly(){
//实现了所有有翅膀的鸭子飞行行为。
}
}
public void fly(){
//什么都不做,不会飞
}
}
针对QuackBehavior的几种具体实现。
public class Quack implements QuackBehavior{
public void quack(){
//实现呱呱叫的鸭子
}
}
public class Squeak implements QuackBehavior{
public void quack(){
//实现吱吱叫的鸭子
}
}
public class MuteQuack implements QuackBehavior{
public void quack(){
//什么都不做,不会叫
}
}
这样的设计,可以让飞行和呱呱叫的动作被其他的对象复用,因为这些行为已经与鸭子类无关了。而我们增加一些新
public class Duck{ --------->在抽象类中,声明各接口,定义各接口对应的方法.
FlyBehavior flyBehavior;//接口
QuackBehavior quackBehavior;//接口
public Duck(){}
public abstract void display();
public void swim(){
//实现游泳的行为
}
public void performFly(){
flyBehavior.fly(); -->由于是接口,会根据继承类实现的方式,而调用相应的方法.
}
public void performQuack(){
quackBehavior.quack();();
}
}
----->通过构造方法,生成'飞','叫'具体实现类的实例,从而指定'飞','叫'的具体属性
public class MallardDuck extends Duck{
public MallardDuck {
flyBehavior = new FlyWithWings ();
quackBehavior = new Quack();
//因为MallardDuck 继承了Duck,所有具有flyBehavior 与quackBehavior 实例变量}
public void display(){
//实现
}
}
这样就满足了即可以飞,又可以叫,同时展现自己的颜色了。
我们只需在Duck中加上两个方法。
FlyBehavior flyBehavior;//接口
QuackBehavior quackBehavior;//接口
public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior {
this.quackBehavior= quackBehavior;
}
}
(1)
在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式
基本概念:
FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.
通常我们将Factory Method作为一种标准的创建对象的方法。
当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模
基本概念:
Singleton 是一种创建性模型,它用来确保只产生一个实例,并提供一个访问它的全局访问点.对一些类来说,保证只有一个实例是很重要的,比如有的时候,数据库连接或 Socket 连接要受到一定的限制,必须保持同一时间只能有一个连接的存在.
在于使用static变量;
创建类对象,一般是在构造方法中,或用一个方法来创建类对象。在这里方法中,加对相应的判断即可。
实例一:
public class Singleton {
private static Singleton s;
public static Singleton getInstance() {
if (s == null)
s = new Singleton();
return s;
}
}
// 测试类
class singletonTest {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1==s2)
System.out.println("s1 is the same instance with s2");
else
System.out.println("s1 is not the same instance with s2");
}
}
s1 is the same instance with s2
实例二:
class Singleton {
static boolean instance_flag = false; // true if 1 instance
public Singleton() {
if (instance_flag)
throw new SingletonException("Only one instance allowed");
else
instance_flag = true; // set flag for 1 instance
}
}
(1)
基本概念:
观察者模式属于行为型模式,其意图是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
思想:
(一)
建立目标(subject)与观察者(observer)接口:
目标(subject)接口:
建立一个注册观察者对象的接口; public void attach(Observer o);
建立一个删除观察者对象的接口; public void detach(Observer o);
建立一个当目标状态发生改变时,发布通知给观察者对象的接口; public void notice();
建立一个当收到目标通知后的更新接口: public void update();
实例:
老师又电话号码,学生需要知道老师的电话号码以便于在合时的时候拨打,在这样的组合中,老师就是一个被观察者
Subject代码:
public interface Subject{
public void attach(Observer o);
public void detach(Observer o);
public void notice();
}
public interface Observer{
public void update();
}
import java.util.Vector;
public class Teacher implements Subject{
private String phone;
private Vector students;
public Teacher(){
phone = "";
students = new Vector();
}
public void attach(Observer o){
students.add(o);
}
public void detach(Observer o){
students.remove(o);
}
public void notice(){
for(int i=0;i<students.size();i++)
((Observer)students.get(i)).update();
}
public void setPhone(String phone){
this.phone = phone;
notice(); --关键
}
public String getPhone(){
return phone;
}
}
public class Student implements Observer{
private String name;
private String phone;
private Teacher teacher;
public Student(String name,Teacher t){
this.name = name;
teacher = t;
}
public void show(){
System.out.println("Name:"+name+"\nTeacher'sphone:"+phone);
}
public void update(){
phone = teacher.getPhone();
}
}
Client代码:
package observer;
import java.util.Vector;
public class Client{ -->可以只定义目标者,观察者,另外的vector,只为了输入结果.
public static void main(String[] args){
Vector students = new Vector();
Teacher t = new Teacher();
for(int i= 0 ;i<10;i++){
Student st = new Student("lili"+i,t);
students.add(st);
t.attach(st);
}
t.setPhone("88803807");
for(int i=0;i<10;i++)
((Student)students.get(i)).show();
t.setPhone("88808880");
for(int i=0;i<10;i++)
((Student)students.get(i)).show();
}
}
(1)
基本概念:
迭代器模式属于行为型模式,其意图是提供一种方法顺序访问一个聚合对象中得各个元素,而又不需要暴露该对象的
至少可以历遍first,next,previous,last,isOver,或是历遍选择符合某种条件的子元素.
(2)
结构:
由一个接口与一个实现类组成.
接口:
主要是定义各历遍的方法.
实现类:
需要一个计算点private int current=0 ; 以及一个容器Vector,来存在原来的进行历遍的一团东西;再对接口方法进
实例:
Iterator接口:
package iterator;
public interface Iterator{
/*
Item:即是集合中的各对象的类型.若为String,即把所有的ITEM改为String,若为其它自定义的类,则改为各自定义的类
*/
public Item first();
public Item next();
public boolean isDone();
public Item currentItem();
}
package iterator;
import java.util.Vector;
public class Controller implements Iterator{
private int current =0;
Vector channel;
public Controller(Vector v){
channel = v;
}
public Item first(){
current = 0;
return (Item)channel.get(current);
}
public Item next(){
current ++;
return (Item)channel.get(current);
}
public Item currentItem(){
return (Item)channel.get(current);
}
public boolean isDone(){
return current>= channel.size()-1;
}
}
package iterator;
import java.util.Vector;
public interface Television{
public Iterator createIterator();
}
HaierTV类实现了Television接口。
package iterator;
import java.util.Vector;
public class HaierTV implements Television{ ---对象
private Vector channel;
public HaierTV(){
channel = new Vector();
channel.addElement(new Item("channel 1")); --各元素,用VECTOR存放
channel.addElement(new Item("channel 2"));
channel.addElement(new Item("channel 3"));
channel.addElement(new Item("channel 4"));
channel.addElement(new Item("channel 5"));
channel.addElement(new Item("channel 6"));
channel.addElement(new Item("channel 7"));
}
public Iterator createIterator(){
return new Controller(channel); --把这个VECTOR放到迭代器中构造方法中去
}
}
Client客户端:
package iterator;
public class Client{
public static void main(String[] args){
Television tv = new HaierTV();
Iterator it =tv.createIterator();
System.out.println(it.first().getName());
while(!it.isDone()){
System.out.println(it.next().getName());
}
}
}
Item类的接口:
package iterator;
public class Item{
private String name;
public Item(String aName){
name = aName;
}
public String getName(){
return name;
}
}
(1)
外观模式属于结构型模式,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式的主要用途就是为子系统的复杂处理过程提供方便的调用方法,使得子系统更加容易被使用。
-->将复杂的过程包含在里面,提供一个简单的应用接口即可.
例如在一个泡茶的过程中,需要作如下的工作:烧开水,准备茶叶,把茶叶放在被子里,把烧开的水放到茶杯中,只
private boolean TeaBagIsSteeped;
public FacadeCuppaMaker(){
System.out.println("FacadeCuppaMaker 准备好冲茶了");
}
public TeaCup makeACuppa(){
TeaCup cup = new TeaCup();
TeaBag teaBag= new TeaBag();
Water water = new Water();
cup.addFacadeTeaBag(teaBag);
water.boilFacadeWater();
cup.addFacadeWater(water);
cup.steepTeaBag();
return cup;
}
}
(1)
适配器模式的意图是将一个已存在的类/接口进行复用,将其转换/具体化成客户希望的另外的一个类/接口。
(2)
如何实例复用:
将要进行复用的类,放到目标类的构造方法中,进行实例化,然后在目标类的相应方法中,进行调用,修改原来方法
public class Adaptee{
public long getPower(long base,long exp){
long result=1;
for(int i=0;i<exp;i++)
result*=base;
return result;
}
}
public interface Target{
public long get2Power(long exp);
}
private Adaptee pt;
public Adapter(){
pt = new Adaptee();
}
public long get2Power(long exp){
return pt.getPower(2,exp); ---修改原来方法中的参数,
}
}
又如:
在SCM中添加的方法:
已有接口:
public boolean updateRecordStates(Double recordId,Double tableNameMapping,int state,boolean
已有实现类:
public boolean updateRecordStates(Double recordId,Double tableNameMapping,int state,boolean
{
return moveTable.updateRecordStates(recordId,tableNameMapping,state,subRecordUpdate);
}
接口:
public boolean updateStatesAdapterForSelfPanel(Double recordId,Double tableNameMapping,int state)
实现类:
public boolean updateStatesAdapterForSelfPanel(Double recordId,Double tableNameMapping,int state)
{
return this.updateRecordStates(recordId,tableNameMapping,state,false);
}
(1)
代理的好处:
--->是可以在间接访问对象的同时,要其前或后,添加其它的逻辑代码.
--->对原来逻辑进行添加其它逻辑,最终生成新的逻辑.即:对类的方法添加一些额外的逻辑,生成新的方法逻辑.
静态代理:
-->一个原类与一个代理类要一一对应。
-->两者都实现共同的接口或继承相同的抽象类;
-->只是在代理类中,实例化原类,在原类方法的前后添加新的逻辑。
如下:
抽象角色:
abstract public class Subject
{
abstract public void request();
}
public class RealSubject extends Subject
{
public void request()
{
System.out.println("From real subject.");
}
}
public class ProxySubject extends Subject
private RealSubject realSubject; //以真实角色作为代理角色的属性
{ realSubject=new RealSubject(); }
{
preRequest();
}
{
//something you want to do before requesting
}
private void postRequest()
{
//something you want to do after requesting
}
}
Subject sub=new ProxySubject();
Sub.request();
动态代理类
Java动态代理类位于Java.lang.reflect包下,一般主要涉及到以下两个类:
1)
Interface InvocationHandler:该接口中仅定义了一个方法:invoke(Object obj,Method method, Object[] args)
2)
Proxy:该类即为动态代理类,其中主要包含以下内容:
Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理类
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后
3)
在使用动态代理类时,我们必须实现InvocationHandler接口,
public interface Subject
{
public void request();
}
import java.lang.reflect.Method;
import java.lang.reflect.InvocationHandler;
public class DynamicSubject implements InvocationHandler {
private Object sub;
public DynamicSubject(Object obj) {
sub = obj;
}
System.out.println("before calling " + method);
return null;
}
==>
method.invoke(sub,args);
其实就是调用被代理对象的将要被执行的方法,方法参数sub是实际的被代理对象,args为执行被代理对象相应操作所
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
{
static public void main(String[] args) throws Throwable
{
RealSubject rs = new RealSubject(); //在这里指定被代理类
InvocationHandler ds = new DynamicSubject(rs); //初始化代理类
Subject subject = (Subject) Proxy.newProxyInstance(rs.getClass().getClassLoader(),rs.getClass
subject.request();
}
实例二:
package dynamicProxy;
public interface Work {
public void startWork();
}
public class JasonWork implements Work {
public void startWork() {
System.out.println("jason start to work...");
}
}
public void startPlay();
}
public void startPlay() {
System.out.println("jason start to play...");
}
}
public static void main(String[] args)
{
JasonWork work=new JasonWork();
InvocationHandler dynamicProxy=new DynamicProxy(work);
Work jasonproxy=(Work)Proxy.newProxyInstance(work.getClass().getClassLoader(),
jasonproxy.startWork();
InvocationHandler dynamicProxy=new DynamicProxy(play);
Play jasonproxy=(Play)Proxy.newProxyInstance(play.getClass().getClassLoader(),
jasonproxy.startPlay();
}
}
===>动态代理类,可以与任何类型的真实类(work/play),进行结合,进行动态的代理.
(1)
State模式定义:
不同的状态,不同的行为; 或者说,每个状态有着相应的行为.
适用场合:
State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.
一个state,包括两部分: 对象 + 对象内部的属性(属性接口+具体属性)
一个对象,要有其属性,以及其setter,getter.且设置好其初始状态+一个调用显示状态的方法(里面就是状态调用自身的显示方法).
一个属性接口,应该有一个执行的方法.
一个具体属性,须包含对象进去,实现方法中,须设置对象下一个要显示的属性-->从而在对象下次调用方法时,其属性值会变化.
代码:
public interface Color {
public void show();
{
Color color;
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public Light()
{
color=new RedColor(this);
}
public void showColor()
{
color.show();
}
}
{
Light light;
public RedColor(Light light)
{
this.light=light;
}
public void show()
{
System.out.println("the color is red,the car must stop !");
System.out.println("write down all logic shoud do this in this state.....");
light.setColor(new GreenColor(light));
}
}
{
Light light;
public GreenColor(Light light)
{
this.light=light;
}
public void show()
{
System.out.println("the color is green,the car can run !");
System.out.println("write down all logic shoud do this in this state.....");
light.setColor(new YellowColor(light));
}
}
{
Light light;
public YellowColor(Light light)
{
this.light=light;
}
public void show()
{
System.out.println("the color is yellow,the car shoud stop !");
System.out.println("write down all logic shoud do this in this state.....");
light.setColor(new RedColor(light));
}
}
public static void main(String[] args) {
Light light=new Light();
//初始调用为红灯
light.showColor();
//再调用为绿灯
light.showColor();
//再调用为黄灯
light.showColor();
//不断调用,不断循环.
}
}
(1)
主要用于创建对象时,运用共享技术,减少对象对内存的占用.一个提高程序效率和性能的模式,会大大加快程序的运
就是说在一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。
新建对象时:
先到hashtable中进行获取-->判断取得对象是否为空-->若是,则新建此对象,且放回hashtable -->若存在,则共享原来
实例: (与静态工厂模式进行对比)
public interface Car {
public void showCarName();
{
public void showCarName()
{
System.out.println("this is the BMWCar .");
}
}
{
public void showCarName()
{
System.out.println("this is the FordCar .");
}
}
{
public static Car car;
public static Car getCar(String name)
{
if("BMW".equals(name))
{
car = new BMWCar();
}
if("Ford".equals(name))
{
car = new FordCar();
}
return car;
}
}
{
public Car car;
private Hashtable<String,Car> carPool=new Hashtable<String,Car>();
public Car getCar(String name)
{
if("BMW".equals(name))
{
car=carPool.get(name);
if(car==null)
{
car=new BMWCar();
carPool.put(name, car);
}
}
if("Ford".equals(name))
{
car=carPool.get(name);
if(car==null)
{
car=new FordCar();
carPool.put(name, car);
}
}
return car;
}
public int getNumber(){ return carPool.getSize(); }
}
CarFlyWeightFactory carFlyWeightFactory=new CarFlyWeightFactory();
Car carf1=carFlyWeightFactory.getCar("Ford");
carf1.showCarName();
Car carf2=carFlyWeightFactory.getCar("Ford");
carf2.showCarName();
if(carf1==carf2)
{
System.out.println("同一部车来的");
}
else
{
System.out.println("不同一部车来的");
}
System.out.println("车的数量是:"+carFlyWeightFactory.getNumber());
}
}
this is the FordCar .
this is the FordCar .
同一部车来的
(1)
Chain of Responsibility职责链模式:
为了避免请求的发送者和接收者之间的耦合关系,使多个接受对象都有机会处理请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
-->
要沿着链转发请求,并保证接受者为隐式的,每个链上的对象都有一致的处理请求和访问链上后继者的接口(即如下实例中,在自己方法中再调用一次相同的方法)。
public class Boy {
private boolean hasCar; // 是否有车
private boolean hasHouse; // 是否有房
private boolean hasResponsibility; // 是否有责任心
}
this.hasCar = hasCar;
this.hasHouse = hasHouse;
this.hasResponsibility = hasResponsibility;
}
return hasCar;
}
this.hasCar = hasCar;
}
return hasHouse;
}
this.hasHouse = hasHouse;
}
return hasResponsibility;
}
this.hasResponsibility = hasResponsibility;
}
}
public void handleRequest(Boy boy);
}
private Handler handler;
}
return handler;
}
this.handler = handler;
}
if (boy.isHasHouse()) {
System.out.println("没想到吧,我还有房子");
} else {
System.out.println("我也没有房");
handler.handleRequest(boy);
}
}
}
this.handler = handler;
}
return handler;
}
this.handler = handler;
}
if (boy.isHasCar()) {
System.out.println("呵呵,我有辆车");
} else {
System.out.println("我没有车");
handler.handleRequest(boy);
}
}
}
this.handler = handler;
}
return handler;
}
this.handler = handler;
}
if (boy.isHasResponsibility()) {
System.out.println("我只有一颗带Responsibility的心");
} else {
System.out.println("更没有责任心");
handler.handleRequest(boy);
}
}
}
public static void main(String[] args) {
// 这个boy没有车,也没有房,不过很有责任心
Boy boy = new Boy(false, false, true);
// 也可以使用setHanlder方法
Handler handler = new CarHandler(new HouseHandler(
new ResponsibilityHandler(null)));
handler.handleRequest(boy);
}
}
如何实例使请求沿着链在各接受对象中传递,当没被第一个接受对象接受时,会传递给第二个对象,若被第一个对象接受了,则不传递下去:
1.各具体的接受对象采用这样的构造方法:
public CarHandler(Handler handler) { this.handler = handler; }
2.各具体的接受对象实现接口的方法handleRequest()中.在调用时,若被接受,则执行true的内容,若不被接受,则执行false的内容,并继续调用再调用handleRequest()方法.
3.在最后的测试类中,生成具体的handler时,用多层包含的形式.这样,在调用了上一层car的方法后,会调用house的相应方法,最后再调用ResponsibilityHandler的方法.
(1)
备忘录模式属于行为型模式,其意图是在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这
实例如下:
有一个对象Employee.除了属性外,还需要一个保存,还原状态的方法.
有一个对象Memento,用来记录Employee每一个时刻的状态,
CareTaker,用来保存,拿回Memento.需要一个保存,还原状态的方法.->需要一个指针,一个容器.
public class Memento{
String name;
int age;
public Memento(String name,int age){
this.name = name;
this.age = age;
}
}
Employee模式:
package memento;
public class Employee{
private String name;
private int age;
public Employee(String aName,int aAge){
name = aName;
age = aAge;
}
public void setName(String aName){
name = aName;
}
public void setAge(int aAge){
age = aAge;
}
public Memento saveMemento(){
return new Memento(name,age);
}
public void restoreMemento(Memento memento){
age = memento.age;
name = memento.name;
}
public int getAge(){
return age;
}
public String getName(){
return name;
}
}
CareTaker代码:
package memento;
import java.util.Vector;
public class CareTaker{
private Vector v;
private int current;
public CareTaker(){
current = -1;
v = new Vector();
}
public void setMemento(Memento mem){
current ++;
v.add(mem);
}
public Memento getMemento(){
if(current>0){
current --;
return(Memento) v.get(current);
}
return null;
}
}
Client代码:
package memento;
public class Client{
public static void show(Employee e){
System.out.println("-----------------------------------");
System.out.println("Name:"+e.getName());
System.out.println("Age:" + e.getAge());
System.out.println("-----------------------------------");
}
public static void main(String[] args){
Employee e = new Employee("lili",25);
CareTaker ct = new CareTaker();
show(e);
ct.setMemento(e.saveMemento());
e.setName("litianli");
show(e);
ct.setMemento(e.saveMemento());
e.setAge(45);
show(e);
ct.setMemento(e.saveMemento());
//restore
e.restoreMemento(ct.getMemento());
show(e);
e.restoreMemento(ct.getMemento());
show(e);
}
}
设计模式——java的更多相关文章
- 【视频】设计模式(Java)视频讲解
设计模式(JAVA) 视频网址: http://www.qghkt.com/ 设计模式(JAVA)视频地址: https://ke.qq.com/course/318643?tuin=a508ea62 ...
- Unity设计模式+Java设计模式,讲解+案例+PPT,一次性学会设计模式,拥抱高薪!
一个程序员对设计模式的理解:“不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开一把锁的模式, ...
- 设计模式-Java版-全-附代码-超生动实例
阅读推荐:设计模式-简单篇 项目地址:https://gitee.com/zwtgit/gof23 学习网站推荐: https://refactoringguru.cn/design-patterns ...
- OOP设计模式[JAVA]——03职责链模式
职责链模式 Responsibility of Chain 在职责链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...
- OOP设计模式[JAVA]——02观察者模式
观察者模式 观察者模式的设计原则 为交互对象之间的松耦合设计而努力,使对象之间的相互依赖降到最低. 观察者模式也是对象行为型模式,其意图为:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时 ...
- Java设计模式--Java Builder模式
1.Java Builder模式主要是用一个内部类去实例化一个对象,避免一个类出现过多构造函数,而且构造函数如果出现默认参数的话,很容易出错. public Person(String name) P ...
- 23种设计模式JAVA 实现目录总结
曾看了不少的有关设计模式的文章,有的提供的实现在现在看来是有些问题,所以现在对以前看过的有关设计模式的文章在这里总结一下,随笔中有引用其他资料,并根据自己的理解重新实现了一次,23种设计模式中,并没有 ...
- OOP设计模式[JAVA]——04命令模式
命令模式 命令模式的意图 命令模式属于对象的行为模式.别名又叫:Action或Transaction. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求 ...
- 单例设计模式-java
在实际项目中单例模式常见应用场景列举如下: 1.servlet编程中,每个servlet就是单例 2.网站计数器,和Application(servlet中涉及) 3.Strucs1框架中,控制器对象 ...
随机推荐
- POJ 3159 Candies (栈优化spfa)
Candies 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/J Description During the kinderga ...
- POJ 2502 Subway
Subway Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4928 Accepted: 1602 Descriptio ...
- VC 各种情况下的窗口句柄的获取
动窗口的句柄.否则,返回值为NULL. GetSafeHwnd 函数功能:获取某个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数. 通过下面的 ...
- RSS阅读器(一)——dom4j读取xml(opml)文件
接触java不久,偶有收获,最近想做一个web版RSS阅读器来锻炼一下.手头有几个从不同版本的foxmail中导出的opml文件,大家应该都知道,opml文件就是xml格式的.那么就先从这里入手,练习 ...
- Unity3D之移植学习笔记:移植到Android平台
首先,我们需要一台已经配置好可以开发Android应用的计算机,这里我使用的是Windows系统+Eclipse+ADT的开发环境,当然也可以使用Android Studio或者使用Mac系统都可以. ...
- 框架学习笔记:Unity3D的MVC框架——StrangeIoC
作为从AS3页游走过来的人,看见StrangeIoC会额外亲切,因为StrangeIoC的设计和RobotLegs几乎一致,作为一款依赖注入/控制反转(IoC)的MVC框架,StrangeIoC除了使 ...
- TypeScript学习笔记(一):介绍及环境搭建
官网 TypeScript目前还在快速的发展中,当前的版本是1.6,有关TypeScript更多的信息可以在其官网中获取. http://www.typescriptlang.org/ 什么是Type ...
- 表与表 不同条件下的关联SQL
USE [ChiefMes]GO /****** Object: StoredProcedure [dbo].[Kenta_RptEmpOEE] Script Date: 05/12/2015 13: ...
- The plot Function in matlab
from http://pundit.pratt.duke.edu/wiki/MATLAB:Plotting The plot Function The plot function is used t ...
- iPhone Push消息全攻略.1
要做一个iPhone Push消息的需求,从简单test的开始. 1.先添加一个app ID 2.点击Edit来配置push服务. 3.生成两个证书,一个用于开发,一个用于发布. 4.按下图操作创建一 ...