创建模式
1.工厂方法模式(Factory Method) 将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到具体的子类。大大提高了系统扩展的柔性,接口的抽象化处理给相互依赖的对象创建提供了最好的抽象模式。
- public class TestFactoryMethod {
-
- public static void main(String[] args) {
-
- AnimalFactory af=new DogFactory();
-
- Animal1 a=af.getAnimal();
-
- }
-
- }
-
- abstract class Animal1{}
-
- class Dog1 extends Animal1{}
-
- class Cat1 extends Animal1{}
-
-
-
- abstract class AnimalFactory{
-
- public abstract Animal1 getAnimal();
-
- }
-
- class DogFactory extends AnimalFactory{
-
- public Animal1 getAnimal(){
-
- System.out.println("Dog");
-
- return new Dog1();
-
- }
-
- }
-
- class CatFactory extends AnimalFactory{
-
- public Animal1 getAnimal(){
-
- System.out.println("Cat");
-
- return new Cat1();
-
- }
-
- }
2.抽象工厂模式(Abstract Factory) 针对多个产品等级的情况,而工厂方法模式针对单一产品等级的情况。
3.单例模式(Singleton) 改善全局变量和命名空间的冲突,可以说是一种改良了的全局变量。这种一个类只有一个实例,且提供一个访问全局点的方式,更加灵活的保证了实例的创建和访问约束。系统中只有一个实例,因此构造方法应该为私有 饿汉式:类加载时直接创建静态实例 懒汉式:第一次需要时才创建一个实例,那么newInstance方法要加同步 饿汉式比懒汉式要好,尽管资源利用率要差。但是不用同步。
- public class TestSingleton {
-
- public static void main(String[] args) {
-
-
-
- }
-
- }
-
- class ClassA{
-
- private static ClassA i=new ClassA();
-
- public static ClassA newInstance(){
-
- return i;
-
- }
-
- private ClassA(){}
-
- }
-
- class ClassB{
-
- private static ClassB i=null;
-
- public static synchronized ClassB newInstance(){
-
- if (i==null) i=new ClassB();
-
- return i;
-
- }
-
- private ClassB(){}
-
- }
4.建造模式(Builder) 将一个对象的内部表象和建造过程分割,一个建造过程可以造出不同表象的对象。可简化为模版方法模式.
- public class TestBuilder {
-
- public static void main(String[] args) {
-
- Builder b=new BuilderImpl1();
-
- Director d=new Director(b);
-
- Product p=d.createProduct();
-
- }
-
-
-
- }
-
- interface Builder{
-
- void buildPart1();
-
- void buildPart2();
-
- void buildPart3();
-
- Product getProduct();
-
- }
-
- class BuilderImpl1 implements Builder{
-
-
-
- public void buildPart1() {
-
- System.out.println("create part1");
-
- }
-
-
-
- public void buildPart2() {
-
- System.out.println("create part2");
-
- }
-
-
-
- public void buildPart3() {
-
- System.out.println("create part3");
-
- }
-
-
-
- public Product getProduct() {
-
- return new Product();
-
- }
-
-
-
- }
-
-
-
- class Director{
-
- Builder b;
-
- public Director(Builder b){
-
- this.b=b;
-
- }
-
- public Product createProduct(){
-
- b.buildPart1(); b.buildPart2();
-
- b.buildPart3();
-
- return b.getProduct();
-
- }
-
- }
-
- class Product{}
5.原型模式(ProtoType) 通过一个原型对象来创建一个新对象(克隆)。Java中要给出Clonable接口的实现,具体类要实现这个接口,并给出clone()方法的实现细节,这就是简单原型模式的应用。 浅拷贝:只拷贝简单属性的值和对象属性的地址 深拷贝:拷贝本对象引用的对象,有可能会出现循环引用的情况。可以用串行化解决深拷贝。写到流里再读出来,这时会是一个对象的深拷贝结果。
结构模式 如何把简单的类根据某种结构组装为大的系统
6.适配器模式(Adapter) 在原类型不做任何改变的情况下,用一个适配器类把一个接口转成另一个接口,扩展了新的接口,灵活且多样的适配一切旧俗。这种打破旧框框,适配新格局的思想,是面向对象的精髓。以继承方式实现的类的 Adapter模式和以聚合方式实现的对象的Adapter模式,各有千秋,各取所长。
- public class TestAdapter {
-
- public static void main(String[] args) {
-
- USB mouse=new Mouse();
-
- PC pc=new PC();
-
-
-
- PS2 adapter=new USB2PS2Adapter(mouse);
-
- pc.useMouse(adapter);
-
- }
-
- }
-
- interface PS2{
-
- void usePs2();
-
- }
-
- interface USB{
-
- void useUsb();
-
- }
-
- class Mouse implements USB{
-
- public void useUsb(){
-
- System.out.println("通过USB接口工作");
-
- }
-
- }
-
- class PC{
-
- public void useMouse(PS2 ps2Mouse){
-
- ps2Mouse.usePs2();
-
- }
-
- }
-
- class USB2PS2Adapter implements PS2{
-
- private USB usb;
-
- public USB2PS2Adapter(USB usb) {
-
- this.usb = usb;
-
- }
-
- public void usePs2(){
-
- System.out.println("把对usePS2的方法调用转换成对useUSB的方法调用");
-
- usb.useUsb();
-
- }
-
- }
7.组合模式(Composite) 把整体和局部的关系用树状结构描述出来,使得客户端把整体对象和局部对象同等看待。
- import java.util.*;
-
- public class TestComposite {
-
- public static void main(String[] args) {
-
- Node n1=new LeafNode(3);
-
- Node n2=new LeafNode(4);
-
- Node n3=new LeafNode(6);
-
- Node n4=new LeafNode(5);
-
- Node n5=new LeafNode(2);
-
- Node n6=new LeafNode(9);
-
- Node n7=new LeafNode(12);
-
- Node n8=new LeafNode(7);
-
- Node n9=new LeafNode(8);
-
- Node c1=new CompositeNode(n1,n2,n3);
-
- Node c4=new CompositeNode(n8,n9);
-
- Node c3=new CompositeNode(n5,c4);
-
- Node c2=new CompositeNode(n4,c3);
-
- Node c5=new CompositeNode(n6,n7);
-
- Node root=new CompositeNode(c1,c2,c5);
-
-
-
- System.out.println(root.getValue());
-
- }
-
- }
-
- abstract class Node{
-
- public abstract int getValue();
-
- }
-
- class LeafNode extends Node{
-
- int value;
-
- public LeafNode(int value){
-
- this.value=value;
-
- }
-
- public int getValue(){
-
- return value;
-
- }
-
- }
-
- class CompositeNode extends Node{
-
- private List children=new ArrayList();
-
- public CompositeNode(Node... nodes){
-
- for(Node n:nodes){
-
- children.add(n);
-
- }
-
- }
-
- public int getValue(){
-
- int result=0;
-
- for(Node n:children){
-
- result+=n.getValue();
-
- }
-
- return result;
-
- }
-
-
-
- }
8.装饰模式(Decorator) 以对客户透明的方式来扩展对象的功能。 用户根据功能需求随意选取组成对象的成分,通过方法的链式调用来实现。 可以给对象动态的增加功能,比继承灵活性更大。
- public class TestDecorator {
-
- public static void main(String[] args) {
-
- Teacher t1=new SimpleTeacher();
-
- Teacher t2=new CppTeacher(t1);
-
- Teacher t3=new JavaTeacher(t2);
-
- t3.teach();
-
-
-
- }
-
- }
-
-
-
- abstract class Teacher{
-
- public abstract void teach();
-
- }
-
- class SimpleTeacher extends Teacher{
-
- public void teach(){
-
- System.out.println("Good Good Study, Day Day Up");
-
- }
-
- }
-
- class JavaTeacher extends Teacher{
-
- Teacher teacher;
-
- public JavaTeacher(Teacher t){
-
- this.teacher=t;
-
- }
-
- public void teach(){
-
- teacher.teach();
-
- System.out.println("Teach Java");
-
- }
-
- }
-
- class CppTeacher extends Teacher{
-
- Teacher teacher;
-
- public CppTeacher(Teacher t){
-
- this.teacher=t;
-
- }
-
- public void teach(){
-
- teacher.teach();
-
- System.out.println("Teach C++");
-
- }
-
- }
9.代理模式(Proxy) 用一个代理对象来作为另一个对象的代理,对客户来说是透明的。 存在一个抽象主题类,具体主题类和代理主题类都继承(实现)抽象主题,代理主题类中的方法会调用具体主题类中相对应的方法。
10.享元模式(Flyweight Pattern) 对象的状态分为内蕴状态和外蕴状态。内蕴状态不随环境变化而变化,因此可以作成系统共享.
11.门面模式(Facade) 访问子系统的时候,通过一个Façade对象访问。Facade类是单例的。 客户代码只需要和门面对象通信,不需要和具体子系统内部的对象通信,使得他们之间的耦合关系减弱。 这次将表现层和逻辑层隔离,封装底层的复杂处理,为用户提供简单的接口,这样的例子随处可见。
门面模式很多时候更是一种系统架构的设计,在我所做的项目中,就实现了门面模式的接口,为复杂系统的解耦提供了最好的解决方案。
12.桥梁模式(Bridge) 将抽象和实现脱耦,使得二者可以单独变化。使得一个继承关系不承担两个变化因素.使用合成来代替继承的一种体现.
- public YuanUser(BankAccount account) {
-
- super(account);
-
-
-
- }
-
- public void getMoney() {
-
- System.out.print("人民币");
-
- account.withdraw();
-
- }
-
- public void saveMoney() {
-
- System.out.print("人民币");
-
- account.deposit();
-
- }
-
-
-
- }
-
- class DollarUser extends BankUser{
-
-
-
- public DollarUser(BankAccount account) {
-
- super(account);
-
-
-
- }
-
- public void getMoney() {
-
- System.out.print("美元");
-
- account.withdraw();
-
- }
-
- public void saveMoney() {
-
- System.out.print("美元");
-
- account.deposit();
-
- }
-
- }
行为模式 描述如何在对象之间划分责任
13.策略模式(Strategy) 如同LayoutManager和具体的布局管理器的关系,在抽象策略类中定义方法,将易于变化的部分封装为接口,通常Strategy 封装一些运算法则,使之能互换。Bruce Zhang在他的博客中提到策略模式其实是一种“面向接口”的编程方法,真是恰如其分。 在具体策略子类中实现,客户代码根据不同的需要选择相应的具体类,例如电子商务中多种价格算法。 一种策略一旦选中,整个系统运行期是不变化的
- public class TestStrategy {
-
- public static void main(String[] args) {
-
- Strategy s1=new May1Strategy();
-
- Strategy s2=new June1Strategy();
-
- Book b=new Book(100);
-
- b.setS(s2);
-
-
-
- System.out.println(b.getPrice());
-
-
-
- }
-
- }
-
-
-
- class Book{
-
- Strategy s;
-
- public Book(double price){
-
- this.price=price;
-
- }
-
- private double price;
-
-
-
- public void setS(Strategy s) {
-
- this.s = s;
-
- }
-
-
-
- public double getPrice(){
-
- return price*s.getZheKou();
-
- }
-
-
-
- }
-
-
-
- interface Strategy{
-
- double getZheKou();
-
- }
-
- class May1Strategy implements Strategy{
-
- public double getZheKou(){
-
- return 0.8;
-
- }
-
- }
-
- class June1Strategy implements Strategy{
-
- public double getZheKou(){
-
- return 0.7;
-
- }
-
- }
14.模板方法(Template Method) 准备一个抽象类,把部分确定的逻辑定义在某些方法中,用其他抽象方法实现剩余的逻辑。不同子类对这些逻辑有不同的实现。 用法:定义多个抽象操作,定义并实现一个模板方法,将步骤放在这个具体方法里,推迟到子类实现。子类可以改变父类的可变部分,但不能改变模板方法所代表的顶级逻辑。
- public class TestTemplateMethod {
-
- public static void main(String[] args) {
-
- XiaoPin xp=new DaPuKe();
-
- xp.act();
-
- }
-
- }
-
- abstract class XiaoPin{
-
- public abstract void jiaoLiu();
-
- public abstract void xuShi();
-
- public abstract void gaoXiao();
-
- public abstract void shanQing();
-
- public final void act(){
-
- jiaoLiu();
-
- xuShi();
-
- gaoXiao();
-
- shanQing();
-
- }
-
- }
-
- class DaPuKe extends XiaoPin{
-
- public void jiaoLiu(){
-
- System.out.println("顺口溜");
-
- }
-
- public void xuShi(){
-
- System.out.println("火车除夕,老同学见面");
-
- }
-
- public void gaoXiao(){
-
- System.out.println("名片当作扑克");
-
- }
-
- public void shanQing(){
-
- System.out.println("马家军");
-
- }
-
- }
15.观察者模式(Observer) 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。观察者和被观察者的分开,为模块划分提供了清晰的界限。在低耦合的对象间完成协调。 Java中的事件模型就是一个应用。
16.迭代器模式(Iterator) 类似于集合中的Iterator,使用迭代器来统一不同集合对象的遍历方式。在绝大多数的系统中,都会用到数组、集合、链表、队列这样的类型,关心迭代模式的来龙去脉非常有必要。在遍历算法中,迭代模式提供了遍历的顺序访问容 器,GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。.NET中就是使用了迭代器来 创建用于foreach的集合。
17.责任链(Chain of Responsibility) 多个处理器对象连成一串,请求在这条链上传递,由该处理这个请求的处理器来处理。发出请求的客户端并不知道哪个对象处理请求。
- public class TestChain {
-
- public static void main(String[] args) {
-
- String pass1="123456";
-
- String pass2="123456";
-
- String personId="123456789012345678";
-
- String email="[email protected]";
-
-
-
- register(pass1,pass2,personId,email);
-
-
-
- }
-
- public static void register(String pass1,String pass2,String personId,String email){
-
- Filter f1=new PasswordFilter1();
-
- Filter f2=new PasswordFilter2();
-
- Filter f3=new PersonIdFilter();
-
- Filter f4=new EmailFilter();
-
-
-
- f1.setNext(f2);
-
- f2.setNext(f3);
-
- f3.setNext(f4);
-
-
-
- System.out.println(f1.doFilter(pass1,pass2,personId,email));
-
- }
-
- }
-
- abstract class Filter{
-
- Filter next=null;
-
- public Filter getNext() {
-
- return next;
-
- }
-
- public void setNext(Filter next) {
-
- this.next = next;
-
- }
-
- public String doFilter(String pass1,String pass2,String personId,String email){
-
- if (next==null) return "成功";
-
- else return next.doFilter(pass1,pass2,personId,email);
-
- }
-
- }
-
- class PasswordFilter1 extends Filter{
-
- public String doFilter(String pass1,String pass2,String personId,String email){
-
- if (!(pass1.equals(pass2)))
-
- return "两次密码输入不一致";
-
- else return super.doFilter(pass1,pass2,personId,email);
-
- }
-
- }
-
- class PasswordFilter2 extends Filter{
-
- public String doFilter(String pass1,String pass2,String personId,String email){
-
- if (pass1.length()!=6)
-
- return "密码长度必须为6";
-
- else return super.doFilter(pass1,pass2,personId,email);
-
- }
-
- }
-
- class PersonIdFilter extends Filter{
-
- public String doFilter(String pass1,String pass2,String personId,String email){
-
- if (personId.length()!=15 && personId.length()!=18)
-
- return "身份证号码非法";
-
- else return super.doFilter(pass1,pass2,personId,email);
-
- }
-
- }
-
- class EmailFilter extends Filter{
-
- public String doFilter(String pass1,String pass2,String personId,String email){
-
- int i1=email.indexOf("@");
-
- int i2=email.indexOf(".");
-
- if (i1==-1 || i2==-1 || i2-i1<=1 || i1==0 || i2==email.length()-1)
-
- return "email非法";
-
- else return super.doFilter(pass1,pass2,personId,email);
-
- }
-
- }
18.状态模式(State) 在对象内部状态改变时改变其行为。把所研究的对象的行为封装在不同的状态对象中。
19.备忘录模式(Memento) 备忘录对象用来存储另一个对象的快照对象,保存其内部状态,使得可以随时恢复。 备忘录角色:保存发起人对象的内部状态,保护内容不被除发起人对象之外的对象获取。窄接口:负责人对象和其他对象看到的接口,只允许把备忘录对象传给其他对象。宽接口:发起人能看到的接口,允许读取内部状态。 发起人角色:创建并使用备忘录对象来保存其状态 负责人角色:负责保存备忘录对象。 白箱实现:备忘录类对其他类也可见,这样发起人的状态可能会存在安全问题。 黑箱实现:把备忘录类作成发起人的内部类,对外提供一个标识接口。