`
zhy20045923
  • 浏览: 155825 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

设计模式学习

阅读更多
面向对象设计原则:
1.单一职责
一个类的功能单一,不该做的不做
2.开放-封闭
对于完成的类,尽量不要修改,如果有需求,可以扩展。对于修改关闭,对于扩展开放
3.依赖到转
细节依赖于抽象,抽象不依赖细节。为了高内聚,低耦合(面向接口编程)
4.里氏替换
子类可以完全替换父类使用。
5.迪米特法则
如果两个类需要直接交互,就通过第三者来进行交互。低耦合


工厂模式Factory:
用于对象封装。需要一个抽象工厂,当用户有需要东西,只需把特征(区别点)告诉工厂,工厂就创建相应的东西。
public class BmwX5Car extends Car {
		public BmwX5Car() {
		}
	}

	public class BmwX7Car extends Car {
		public BmwX7Car() {
		}
	}

	public class SimpleCarFactory {
		// 简单工厂

		public Car createCar(String type) {
			if ("bmwx5".equals(type)) {
				return new BmwX5Car();
			} else if ("bmwx7".equals(type)) {
				return new BmwX7Car();
			} else
				return null;
		}
	}

工厂方法模式Factory Method:
用于对象封装。需要一个抽象工厂接口,然后定义不同的工厂创建对象。与工厂的区别在于,对创建什么对象的决策是否透明(对于客户,知道创建什么对象)。

抽象工厂模式:
对于工厂方法的高度抽象,不仅对工厂进行接口抽象,对工厂生产的东西也进行接口抽象。

策略模式Strategy:
类似于工厂模式,用于对行为,算法封装。需要根据特征(区别点)调用相应的实现方法。
定义一个抽象类,其中算法不同的方法由子类实现。
public interface Strategy {
		boolean isPrime();
	}

	public class Miller implements Strategy {
		public boolean isPrime() {
			boolean result = false;
			System.out.println("这里是用来写Miller策略获取结果!");
			return result;
		}

	}

	public class Fermat implements Strategy {
		public boolean isPrime() {
			boolean result = false;
			System.out.println("这里是用来写Fermat策略获取结果!");
			return result;
		}
	}

	public class Primality {
		private Strategy strategy; // 私有的接口

		public Primality(Strategy s) {
			strategy = s;
		}

		public boolean run(int n) {
			return strategy.isPrime();
		}
	}

	public class TestStrategy {
		public static void main(String[] args) {
			Primality prime = null;
			int n = 1;
			Character ch = 'm';
			switch (ch) {
			case 'l':
			case 'L':
				prime = new Primality(new Miller());
				break;
			case 'm':
			case 'M':
				prime = new Primality(new Fermat());
				break;
			}
		}
	}

装饰模式Decorator:
实现子类之间的方法的相互调用,也可以说是子类通过别的子类进行功能扩展。具体实现是通过在子类中通过父类的对象,显式的调用子类所继承的父类方法。然后在使用时,通过一个子类初始化另一个子类,这个过程就叫做装饰。
例子地址:http://apps.hi.baidu.com/share/detail/2044628
	public abstract class Car {
        String name = "Unknow Car";
        public String getName() {
            return this.name;
        }
        public abstract float cost();
    }
    // 标准型 BMW 汽车
    public class BmwCar extends Car {
        public BmwCar() {
            this.name = "BMW";
        }
        @Override
        public float cost() {
            return 50 * 10000.00f;
        }
    }

    // 标准 QQ 汽车
    public class QQCar extends Car {
        public QQCar() {
            this.name = "QQ";
        }

        @Override
        public float cost() {
            return 3 * 10000.00f;
        }
    }

    // 配件装饰者
    public abstract class AccesoryDecorator extends Car {
        public abstract String getName();
    }

    // 安全气囊配件
    public class AirbagAccesory extends AccesoryDecorator {
        private Car car;
        public AirbagAccesory(Car car) {
            this.car = car;

        }
        @Override
        public String getName() {
            return car.getName() + ",Airbag";

        }
        @Override
        public float cost() {
            return car.cost() + 1500;
        }
    }

    // 摄像头配件
    public class CameraAccesory extends AccesoryDecorator {
        private Car car;
        public CameraAccesory(Car car) {
            this.car = car;
        }
        @Override
        public String getName() {
            return car.getName() + ",Camera";
        }
        @Override
        public float cost() {
            return car.cost() + 800;
        }
    }

    // 测试程序

        public static void main(String[] args) {
            Car car1 = new AirbagAccesory(new CameraAccesory(new QQCar()));
            printCarInfo(car1);
            Car car2 = new AirbagAccesory(new CameraAccesory(new BmwCar()));
            printCarInfo(car2);
            
        }
        public static void printCarInfo(Car car) {
            System.out.println("Car Name:" + car.getName() + ",Cost:"+ car.cost());
        }

代理模式Proxy:
这个模式就是两个实现相同接口的类,一个是具体的实现类(真实类),从中访问外部数据,另一个是通过实现类的方法访问外部对象(代理类)。但是应用只能够知道代理类,不知到实现类。代理模式在web应用常见。
//抽象角色:
abstract public class Subject{      
     abstract public void request();
}

//真实角色:实现了Subject的request()方法。
public class RealSubject extends Subject{
     public RealSubject(){
     }
     public void request(){
           System.out.println("From real subject.");
     }
}

//代理角色:
public class ProxySubject extends Subject{
     private RealSubject realSubject; //以真实角色作为代理角色的属性
      public ProxySubject(){
      }
     public void request(){ //该方法封装了真实对象的request方法
         preRequest();
         if( realSubject == null ){
               realSubject = new RealSubject();
         }
         realSubject.request(); //此处执行真实对象的request方法
           postRequest();
      }
     private void preRequest(){
      //something you want to do before requesting
     }
     private void postRequest(){
     //something you want to do after requesting
     }
}

//客户端调用:
Subject sub=new ProxySubject();
Sub.request(); 

外观模式(门面模式)Facade:
这个模式和代理模式类似,都是对行为进行屏蔽(实现细节),为子系统中的各个接口的操作提供一个供外部调用的通用的接口。与代理模式不同的是,代理模式的代理类和实现类出于同一接口,外观是通过通用接口将各个接口进行了组合。
 // 电源
	 public class Power {
	 public void connect() {
	 System.out.println("The power is connected.");
	 }
	
	 public void disconnect() {
	 System.out.println("The power is disconnected.");
	 }
	 }
	
	 // 主板
	 public class MainBoard {
	 public void on() {
	 System.out.println("The mainboard is on.");
	 }
	
	 public void off() {
	 System.out.println("The mainboard is off.");
	 }
	 }
	
	 // 计算机外观
	 public class Computer {
	 private Power power;
	 private MainBoard board;
	 public Computer(Power power, MainBoard board) {
	 this.power = power;
	 this.board = board;
	 }
	
	 public void startup() {
	 this.power.connect();
	 this.board.on();
	 }
	
	 public void shutdown() {
	 this.board.off();
	 this.power.disconnect();
	 }
	 }

中介者模式():
类似与门面模式,门面模式是介于客户程序与子系统之间的,而中介者模式是介于子系统与子系统之间的。

原型模式Prototype:
通过初始化一个对象(必须实现object的clone方法),通过clone的方法生成其他的对象进行使用。clone属于浅拷贝,copy属于深拷贝,浅拷贝是引用传递,深拷贝是值传递。所以,对于普通类型的数据,通过clone后,可以按照要求进行修改,不会影响原始对象的值,但是对于引用类型的数据,修改后会影响原始对象。

模板方法模式Template:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。将一些共同的方法或执行步骤抽象到父类中,不同的部分通过接口(抽象方法)让子类实现。子类就可以做到不改变算法的结构就可以做到自定义算法的某些特定细节。
// 导游
	public abstract class Guide {
		public final void leadTour() {
			this.buyTickets();
			if (needRest()) {// 钩子
				this.bookingHotel();
			}
			this.visit();
			this.getBack();

		}

		// 购买旅行票
		public abstract void buyTickets();

		// 预定旅店
		public abstract void bookingHotel();

		// 参观
		public void visit() {
			System.out.println("Visit the scenic spot.");
		}

		// 返回
		public abstract void getBack();

		// 是否需要住宿
		public boolean needRest() {
			return true;
		}
	}

	public class BeiJingGuide extends Guide {
		@Override
		public void buyTickets() {
			System.out.println("Buy bus tickets.");
		}

		@Override
		public void bookingHotel() {
			// 因为不需要住宿,所以这里什么都不做
		}

		@Override
		public void getBack() {
			System.out.println("Get back by bus.");
		}

		// 覆盖钩子,取消住宿
		@Override
		public boolean needRest() {
			return false;
		}
	}

	public class HaiNanGuide extends Guide {
		@Override
		public void buyTickets() {
			System.out.println("Buy plane tickets.");
		}

		@Override
		public void bookingHotel() {
			System.out.println("Booking HaiNan Hotel.");
		}

		@Override
		public void getBack() {
			System.out.println("Get back by air.");
		}
	}

建造者模式(生成器模式)Builder:
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。该模式与模板方法模式非常相似,只是比模板方法模式多了一个指挥类,该类用于固定构建过程,相当于模板中的固定算法骨架的功能。

观察者模式Observer:
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听同一个主体对象(被观察者),如果主体对象在状态改变时,会通知所有的观察者,以便更新自己。观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来。最好是通过抽象类(接口)进行相互关联。
主要解决一(主题subject)对多(observer)的问题,如果主题变,就要通知所有的observer。实现,subject定义observer的容器变量和关联因子,如果关联因子变化,就要执行容器中每一个observer的update方法。
// 博客
	public interface Subject {
		public void addObserver(Observer observer);

		public void removeObserver(Observer observer);

		public void notifyObservers();
	}

	interface Observer {
		public void update(String blog);
	}

	class Blogger implements Subject {
		private List<Observer> observers;
		private String blog;

		public Blogger() {
			observers = new ArrayList<Observer>();
		}

		public void addObserver(Observer observer) {
			observers.add(observer);

		}

		public void removeObserver(Observer observer) {
			observers.remove(observer);
		}

		public void notifyObservers() {
			for (Observer o : observers) {

				o.update(blog);

			}
		}

		// 发表新博客文章
		public void writeNewBlog(String blog) {

			this.blog = blog;

			notifyObservers();

		}
	}

	// 邮件订阅者
	public class EmailSubscriber implements Observer {
		public void update(String blog) {
			// 发送电子邮件
		}
	}

	// RSS 订阅者
	public class RssSubscriber implements Observer {
		public void update(String email) {
			// 更新 RSS 信息
		}
	}

状态模式State:
状态模式用于消除大量的分支判断。把状态的逻辑判断转移到表示不同状态的一系列类中,就可以把复杂的判断简单化。定义n个状态类(继承一个父类),在每一个状态类中有两种可能,一是自己处理,二是传给下一状态类处理。
public abstract class State{
		int type;
		public void setType(int t){
			type = t;
		}
	    public abstract void doSomething();
	}
	public class Angry extends State{
		public void doSomething(){
			if(type > 0){
				System.out.println("I'm angry!");
			} else {
				new Happy().doSomething();
			}
	    }
	}
	
	public class Happy extends State{
	    public void doSomething(){
			if(type < 0){
				System.out.println("I'm happy!");
			} else {
				new Angry().doSomething();
			}
	    }
	}
	
	public static void main(String[] ss){
		State happy = new Happy();
		happy.setType(-1);
		happy.doSomething();
	}

职责连模式(Chain of responsibility):
和状态模式类似,是对请求处理类的封装。状态模式一般适用与if else ,职责连适用与switch,状态模式的下一步处理对象是由内部(编译)决定的,但是职责连的下一步处理对象是由客户端决定的。

适配器模式(Adapter):
将一个客户无法使用的东西(源),通过中间件(适配器)转换为可以使用的东西(目标)。当然,适配器需要继承目标。适用与功能都实现了,但是由于接口无法不同导致无法使用,此时中间插入一个转换层做适配,就可以解决。

备忘录模式(Memento):
在不破坏封装的前提下,捕获一个对象的状态,并且在对象之外保存,以便随时恢复。适用于需要维护历史数据的情况。需要定义一个备忘类(状态bean),管理类(备忘类bean)。客户端通过管理类,可以保存或恢复状态。

组合模式(Composite):
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式对单个对象的使用和组合对象的使用具有一致性。抽象构件类(Component),叶子构件类(leaf),树枝构件类(Composite),客户类(Client)。客户通过对接口(component)的使用,将一个个构建(leaf,composite)组合起来。
public interface IMenu {
		// 取得名称
		public String getName();

		// 显示
		public void display();

		// 添加菜单
		public void addItem(IMenu menu);
	}

	public class Menu implements IMenu {
		private List<IMenu> items = new ArrayList<IMenu>();
		private String name;

		public Menu(String name) {
			this.name = name;
		}

		public void addItem(IMenu menu) {
			items.add(menu);
		}

		public void display() {
			System.out.println(this.name + ":Menu");
			for (IMenu menu : items) {
				menu.display();
			}
		}

		public String getName() {
			return this.name;
		}
	}

	public class MenuItem implements IMenu {
		private String name;

		public MenuItem(String name) {
			this.name = name;
		}

		public void display() {
			System.out.println(this.name + ":MenuItem");
		}

		public String getName() {
			return this.name;
		}

		public void addItem(IMenu menu) {
			throw new UnsupportedOperationException();
		}

	}

	public class MenuBar {
		private List<IMenu> menus = new ArrayList<IMenu>();
		public void addMenu(IMenu menu) {
			this.menus.add(menu);
		}
		public void display() {
			System.out.println(":MenuBar");
			for (IMenu menu : menus) {
				menu.display();
			}
		}
	}


迭代器模式(Iterator pattern):
提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。一般封装3个方法next(),hasNext(),remove();该模式应该可以废弃,因为现在语言已经集成了该模式。

单例模式(Singleton):
保证一个类只有一个实例,且提供一个访问它的访问点,饿汉式(提前创建好对象),懒汉式(使用时创建)。
public class Singleton {
	private volatile static Singleton instance;
	private Singleton() {
	}
	public static Singleton getInstance() {
		synchronized (Singleton.class) {
			if (instance == null) {
				instance = new Singleton();
			}
		}
		return instance;
	}
}

桥接模式(Bridge):
将抽象和实现分离,使他们独立变化。即实现系统可能有多个分类,每个分类都有可能变化,就把每个变化分离出来,减少他们之间的藕合。

命令模式(Command):
将一个请求(command)封装成一个对象,从而可以让你用不同的请求对客户(receiver)进行参数化,对请求进行记录或日志,支持撤销操作(invoker)。
invoker通知command执行请求,command执行receiver的具体要求。
public class Mp3Player {
		public void playMusic() {
			System.out.println("Music is playing.");
		}

		public void stopMusic() {
			System.out.println("Music is stopped.");
		}
	}

	public interface Command {
		public void execute();

		public void undo();
	}

	public class PlayMusicCommand implements Command {
		private Mp3Player player;

		public PlayMusicCommand(Mp3Player p) {
			this.player = p;
		}

		public void execute() {
			this.player.playMusic();
		}

		public void undo() {
			this.player.stopMusic();
		}
	}

	// 停止音乐命令
	public class StopMusicCommand implements Command {
		private Mp3Player player;

		public StopMusicCommand(Mp3Player p) {
			this.player = p;
		}

		public void execute() {
			this.player.stopMusic();
		}

		public void undo() {
			this.player.playMusic();
		}
	}

	public class NoCommand implements Command {
		public void execute() {
		};

		public void undo() {
		};
	}
	
	public class remoteControl{
		private Command[] cm;
		private Command preCM;
		public remoteControl(){
			 cm = new Command[3];
			 for(int i =0;i< 3;i++){
				 cm[i] = new NoCommand();
			 }
		}
		public void setCommand(int index, Command c) {
			cm[index] = c;
		}
		public void doCommond(int index){
			cm[index].execute();
			preCM = cm[index];
		}
		public void cancleCommond(int index){
			preCM.undo();
		}
	}
	

享元模式(Flyeight):
它用来解决大量相同对象被多次实例化,从而导致内存被大量占用的情况。享元模式中关键要理解“内蕴状态”(Internal State)和“外蕴状态”(External State)这两个概念。
内蕴状态:存储在享元对象内部,不随着环境改变,要以被诸多对象共享。
外蕴状态:一般由客户端指定,并传入享元对象内部,它随着环境进行变化。
抽象享元(Flyweight):为具体享元规定出需要实现的公共接口。
具体享元(ConcreteFlyweight):实现抽象享元角色所规定的接口。如果有“内蕴状态”的话,将“内蕴状态”声明为成员变量,从而使享元对象拥用固定的“内蕴状态”。
享元工厂(FlyweightFactory):负责创建和管理享元角色,保证享元对象可以被共享。当一个客户端对象调用一个享元对象的时候,享元工厂角色会检查系统中是否已经有符合要求的享元对象。如果已经有了,享元工厂就应当提供这个现有享元对象;如果系统中没有适当的享元对象,享元工厂角色就应当创建一个合适的享元对象。
客户端(Client):维护一个对所有享元对象的引用。提供与管理享元对象的“外蕴状态”。

解释器模式(Interpreter):
它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。

访问者模式(Visitor):
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
  1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具休访问者的具休元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
  2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。
  3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。
  4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。
  5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

分享到:
评论

相关推荐

    《设计模式学习笔记》

    《设计模式学习笔记》主要探讨了GOF的23种设计模式以及类设计的基本原则,旨在帮助开发者理解和应用这些经过时间验证的成熟解决方案。设计模式是面向对象软件设计中的核心概念,它们为解决常见的设计问题提供了标准...

    Head First 设计模式(高清中文完整版带目录+附书源码+HeadFirst设计模式学习伴侣.rar).7z.002(2-2)

    Head First 设计模式(高清中文完整版带目录)+附书源码+HeadFirst设计模式学习伴侣.rar 又名: Head First Design Patterns 作者: (美)弗里曼(Freeman,E.) 副标题: Head First Design Patterns 简介 ·····...

    HeadFirst设计模式学习伴侣.jpg

    HeadFirst设计模式学习伴侣.jpg

    设计模式学习 ppt

    这个“设计模式学习ppt”资料包显然是一份面向初学者或大学生的教学资源,通过十四个PPT文件深入浅出地讲解了设计模式的各个方面。 首先,我们来看设计模式的基本概念。设计模式是对在特定上下文中反复出现的问题...

    Java设计模式学习.pdf

    文档中描述的是Java设计模式学习笔记,目前涉及了7种设计模式,但没有具体指明这7种模式是什么,计划后续增加更多的模式。虽然文件内容中存在OCR扫描的识别错误,但不影响我们从整体上把握设计模式的脉络和学习方法...

    java设计模式学习

    本资料“java设计模式学习”包含了对设计模式的深入理解和实际应用,通过简单实用的例子,帮助开发者掌握如何在Java项目中运用设计模式。 首先,我们要介绍的是工厂模式。工厂模式是一种创建型设计模式,它提供了一...

    设计模式学习总结.doc

    在《设计模式学习总结》中,作者通过自己的学习经历和实际应用,分享了对23种经典设计模式的理解和感悟。这篇文档主要讨论了设计模式的概念、作用、应用以及学习设计模式时应注意的误区。 设计模式起源于面向对象...

    设计模式学习资料

    Java设计模式,解说通俗易懂,推荐新手学习使用,文档中包含类图

    设计模式学习.zip

    本资源"设计模式学习.zip"聚焦于C++编程语言中的设计模式应用,是2017年的一次黑马程序员培训课程的配套代码,旨在帮助学习者通过实际的代码示例来理解和掌握设计模式。 在C++中,设计模式主要分为三大类:创建型...

    设计模式学习笔记.ppt

    设计模式学习笔记.ppt 自己写的一点学习笔记。

    设计模式学习系列2设计模式影印版

    《设计模式学习系列2设计模式影印版》作为一套学习资料,专注于介绍设计模式的核心理念与实践应用,为读者提供了一个系统性的学习框架。 设计模式主要分为三类:创建型模式、结构型模式和行为型模式。其中,创建型...

    C# 设计模式学习 源码

    本资料包“C# 设计模式学习 源码”包含了作者在学习设计模式过程中的笔记和源码示例,对于想要深入理解C#设计模式的人来说是一份宝贵的资源。 设计模式分为三大类:创建型、结构型和行为型。下面将详细介绍这些类别...

    设计模式学习资料设计模式学习资料

    设计模式学习资料设计模式学习资料

    head first设计模式学习代码

    《Head First设计模式学习代码详解》 设计模式是软件工程中的宝贵经验总结,它提供了一套通用的解决方案模板,帮助开发者在面对复杂问题时能够快速有效地进行设计和开发。Head First设计模式是一本非常受欢迎的设计...

    C++设计模式学习框架

    "C++设计模式学习框架"是一个专为学习和实践这些模式而构建的资源集合,它涵盖了各种常见的设计模式,帮助开发者深入理解并熟练应用到实际项目中。 设计模式通常分为三类:创建型模式(Creational Patterns)、结构...

    设计模式学习经典篇之菜鸟篇

    本资源“设计模式学习经典篇之菜鸟篇”旨在为初学者提供一个全面而通俗易懂的设计模式学习路径。 设计模式的核心在于重用已验证的解决方案,以提高代码的可读性、可维护性和可扩展性。根据GOF(Gamma, Helm, ...

    JAVA设计模式学习【技术文档】

    ### Java设计模式学习概述 #### 标题解读 文档标题为“JAVA设计模式学习【技术文档】”,表明这是一份专注于Java语言的设计模式学习资源。设计模式作为软件工程领域的重要组成部分,它提供了一系列面向对象设计问题...

    设计模式学习指南第一节

    《设计模式学习指南》是一份详细介绍设计模式的资源,旨在帮助开发者理解和掌握设计模式的精髓。 设计模式的学习对于任何想要提升其软件设计能力的人来说都是至关重要的。它可以帮助我们遵循一些核心的设计原则,...

    设计模式学习帮助文档中文字幕高清

    本资源包含的设计模式学习帮助文档和高清中文字幕,旨在提供一个系统化的学习路径,帮助初学者和经验丰富的开发者深入理解并应用设计模式。 设计模式分为三大类:创建型模式、结构型模式和行为型模式。创建型模式...

Global site tag (gtag.js) - Google Analytics