首页 > 代码库 > java设计模式-创建型

java设计模式-创建型

1.设计模式介绍

1.1 设计模式的概念
     1.设计模式是一套被反复使用,多数人知晓,经过分类编码目的的优秀代码设计经验的总结。
     2.设计模式贯彻的原理:面向接口编程,而不是面向对象实现。
     3.设计模式的目标:降低耦合性,增强灵活性。
    1.2 设计模式的要素
     1.模式名称
     2.问题
     3.环境与初始环境
     4.解决方案
     5.效果
     6.举例
     7.末态环境
     8.推理
     9.其他有关模式
     10.已知的应用
    1.3设计模式的分类
     1.创建型
      1.1  单例模式
      1.2  工厂模式
      1.3  抽象工厂模式
      1.4  建造者模式
      1.5  原型模式
     2.结构型
      1.1  代理模式
      1.2  装饰模式
      1.3  适配器模式
      1.4  组合模式
      1.5  桥梁模式
      1.6  外观模式
      1.7  享元模式
     3.行为型
      1.1  模板方法模式
      1.2  命令模式
      1.3  责任连模式
      1.4  策略模式
      1.5  迭代器模式
      1.6  中介者模式
      1.7  观察者模式
      1.8  备忘录模式
      1.9  访问者模式
      1.10 状态模式
      1.11 解释器模式
     1.4 模式解释
      1.单例模式
       singleton Pattern:一个类只有一个实例,而且自行实例化并向整个系统提供整个实例。
      2.工厂模式
       Factory Pattern:在工厂模式中,工厂类成为抽象类,实际的创建实例的工作则推迟到子
       类中去,工厂方式的用以是定义一个创建对象的工厂接口,将实际创建工作由其子类完成。
      3.抽象工厂模式
       Abstract Factory:抽象工厂是所有工厂模式中最为抽象和最具有一般性的一种形态,抽象
       工厂可以向客户提供一个接口,使得客户可以在不必指定产品具体类型的情况下,创建多个产品族中
       的对象产品,强调的是系列对象的变化。
      4.建造者模式
       Builder Pattern:把构造对象实例的逻辑移到类的内部,在类的外部定义了该类的逻辑构造
       ,它把一个复杂对象的构造过程从对象的表示中分离出来,其直接效果是将一个复杂的对象简化成一个
       比较简单的目标对象,强调的是产品的构造过程。
      5.原型模式
       Prototype Pattern:原型模式和工厂模式一样,同样隐藏了客户隐藏了对象的创建工作,但与之
       通过对一个类进行实例化来构造新对象不同的是,原型模式是通过复制一个现有的对象,生产新的对象。
      6.代理模式
       Proxy:为其他对象提供一种代理以控制对该对象的访问
      7.装饰模式
       Decorator:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
      8.适配器模式
       Adapter:将一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起
       工作的两个类能够一起工作
      9.组合模式
       Composite:将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象
       的使用具有一致性
      10.桥梁模式
       Bridge:将抽象和实现解耦,使得两者可以独立变化.
      11.外观模式
       Facede:要求一个子系统的外部与其内部通信必须通过一个统一的对象进行,外观模式提供一个高层次的接口
       使得子系统更易于使用
      12.享元模式
       Flyweight:是池技术的重要实现方式,使用共享对象可以有效的支持大量的细粒度的对象
      13.模板方法模式
       Template Method:定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法
       的结构就可以重新定义该算法的某些特定步骤
      14.命令模式
       Command:是一种高内聚的模式,将一个请求封装成一个对象,从而使用不同的请求把哭客户端参数化,对请求的排队
       或者记录请求日志,可以提供命令的撤销和恢复功能
      15.责任连模式
       Chain of Responsibility:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系
       将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止.
      16.策略模式
       Strategy:定义一组算法,将每个算法封装起来,并且使它们之间可以互换.
      17.迭代者模式
       Iterator:提供一种方法访问一个容器对象中的各个元素,而又不需要暴露该对象的内部细节.
      18.中介者模式
       Mediator:用一个中介对象封装一系列的对象交互,中介者使得各个对象不需要要显示地相互作用,从而使其解耦
      19.观察者模式
       Observer:也叫发布订阅模式,定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态的时候,则所有依
       赖它的对象都会得到通知并且被自动更新
      20.备忘录模式
       Memento:在不破坏封装性的前提下,捕获一个对象的内部状态,在改对象之外保存该对象的状态
      21.访问者模式
       Visitor:封装一些作用于某种哦个数据结构中各个元素的操作,它可以在不改变数据结构的前提下,定义作用域这些
       元素的新操作.
      22.状态模式
       State:当一个对象内在状态改变时允许其改变行为,整个对象看起来像改变了其类型,状态模式的核心是封装,状态的变更
       引起行为的变更.
      23.解释器模式
       Interpreter:定义一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器的作用使得该文法表示来解释语言中的句子.

2.设计原则

2.1单一职责原则的定义
   Single Responsibility Principle 简称SRP
   There should be more than one reason for a class t change
   一个类应该只有一个引起它变化的原因,即一个类应该只有一个职责(不唯一) 
   类的职责越少,则对象之间的依赖关系就越少,耦合度就会减少,受其他对象的约束与牵制也会减少
   从而保证了系统的可扩展性.
   单一职责的有点:
    1.降低类的复杂性
    2.提高类的可读性
    3.提高代码的可维护性和复用性
    4.降低因变更引起的风险
   里氏替换原则
      继承的优点:
    1.代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性
    2.提高代码的可重用性
    3.提高代码的可扩展性
    4.提高产品或项目的开放性
      继承的缺点:
    1.继承是入侵式的,只要继承就会拥有父类的属性和方法
    2.降低代码的灵活性,子类必须拥有父类的属性和方法,使子类收到限制
    3.增强耦合性,当父类需要大量修改的时候,子类也受到影响
     原则:
     凡是能够使用父类的地方都可以无缝的使用其子类代替使用而整个程序没有受到
     影响,符合里氏替换原则,即子类不仅拥有父类的属性和方法,还进行了自身的扩展
     1.子类必须完全实现父类的方法(访问权限只能扩大而不能缩小)
     2.子类可以拥有自己的个性(对父类进行扩展)
     3.覆盖或实现父类的方法的时候,参数可以被放大(参数可以增加)
     4.覆盖或实现父类的方法的时候,结果可以缩小(返回结果返回减小)
    依赖倒置原则
       1.高层模块不应该依赖底层模块
       2.抽象不依赖于具体
       3.细节应该依赖抽象
       4.模块间的依赖通过抽象发生,实现类之间不发生之间的依赖关系,其依赖关系是通过接口或者抽象类来产生
       5.接口或者抽象类不依赖于实现类
       6.实现类依赖于接口或者抽象类
       7.每个类都尽量具有接口或抽象类,或者抽象类和接口两者都具备,这是依赖倒置的基本要求
        接口和抽象类都是抽象的,有了抽象才可能有依赖倒置
       8.变量的表面类型尽量都是接口或者抽象类
       9.任何类型都不应该从具体派生
       10.尽量不要重写基类的方法
   接口隔离原则
       1.一个类对另外一个类的依赖性应当是建立在最小的接口上的
       2.一个接口代表一个角色,不宜过高将不同的角色都交给一个接口,没有关系的接口
       合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染
       3.不应该强迫客户依赖于它们不用的方法
  迪米特法则
       也叫最少知识原则,意思是一个对象应该对其他对象尽可能的少的了解.
       1.尽量与你直接的朋友进行通信
       2.不要跟陌生对象说话
       3.每一个软件单位对其他的单位都只有最少的了解
  开闭原则
       一个软件实体应该只对扩展开放,而对修改关闭
       1.开闭原则提高复用性
       2.开闭原则提高维护性
       3.开闭原则提高灵活性
       4.开闭原则利于测试

3.设计模式

3.1

单例模式-恶汉模式

package model.create.badmash;

/**
 * @des 恶汉模式
 * @author felayman
 * @Time 下午4:22:43
 * @Email <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class Singleton {
	private static Singleton instance = new Singleton();

	public static Singleton getInstance() {
		return instance;
	}
}

单例模式-懒汉模式

package model.create.lazybones;
/**
 * @des  懒汉模式
 * @author felayman
 * @Time   下午4:26:10	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class Singleton {
	private static Singleton  instance= null;
	private Singleton(){
		
	}
	public static Singleton getInstance(){
		if(instance==null){
			synchronized (Singleton.class) {
				instance = new Singleton();
			}
		}
		return instance;
	}
}

3.2 工厂模式

package model.create.factory;
/**
 * @des  工厂类,创建一个产品对象,其输入参数类型可以自行设置
 * @author felayman
 * @Time   下午4:29:07	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public interface Creator {
	public <T extends Product> T factory(Class<T>c);
}
package model.create.factory;
/**
 * @des  产品类的公共方法
 * @author felayman
 * @Time   下午4:29:53	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public interface Product {
	public void method1();
	public void method2();
}


package model.create.factory;
/**
 * @des 具体的产品类生产者
 * @author felayman
 * @Time   下午7:08:31	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class ConcreteCreator  implements Creator{
	public <T extends Product> T factory(Class<T> c) {
		Product product = null;
		Product newInstance = null;
		try {
			newInstance = (Product) Class.forName(c.getName()).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		product = newInstance;
		@SuppressWarnings("unchecked")
		T t = ((T) product);
		return t;
	}

}
package model.create.factory;
/**
 * @des  具体的产品类
 * @author felayman
 * @Time   下午7:09:17	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class ConcretePruduct implements Product{

	public void method1() {
		
	}

	public void method2() {
		
	}
	
}


package model.create.factory;
/**
 * @des  测试类
 * @author felayman
 * @Time   下午7:09:44	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class FactoryTest {
	public static void main(String[] args) {
		Creator creator = new ConcreteCreator();
		@SuppressWarnings("unused")
		Product product = creator.factory(ConcretePruduct.class);
		/*
		 * 继续处理其他业务
		 */
	}
}

3.3建造者模式

package model.create.build;
/**
 * @des  建造者模式所要创建的对象模板
 * @author felayman
 * @Time   下午4:49:52	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public abstract class Computer {
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getCpu() {
		return cpu;
	}
	public void setCpu(String cpu) {
		this.cpu = cpu;
	}
	public String getRam() {
		return ram;
	}
	public void setRam(String ram) {
		this.ram = ram;
	}
	public String getHardDisk() {
		return hardDisk;
	}
	public void setHardDisk(String hardDisk) {
		this.hardDisk = hardDisk;
	}
	public String getOs() {
		return os;
	}
	public void setOs(String os) {
		this.os = os;
	}
	private String type;
	private String cpu;
	private String ram;
	private String hardDisk;
	private String os;
	
}


package model.create.build;
/**
 * @des  建造者的标志
 * @author felayman
 * @Time   下午4:58:37	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public interface ComputerBuilder {
	//建造cpu
	public void buildCpu();
	//建造ram
	public void buildRam();
	//建造硬盘
	public void buildHardDisk();
	//建造显卡
	public void buildGraphicCard();
	//建造显示器
	public void buildMonitor();
	//建造操作系统
	public void buildOS();
	//得到建造好的计算机
	public Computer getResult();
}


package model.create.build;
/**
 * @des  建造者模式所想创建的具体对象
 * @author felayman
 * @Time   下午4:55:17	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class Dell extends Computer{
	private String graphicCard;
	private String monitor;
	public String getMonitor() {
		return monitor;
	}

	public void setMonitor(String monitor) {
		this.monitor = monitor;
	}

	public String getGraphicCard() {
		return graphicCard;
	}

	public void setGraphicCard(String graphicCard) {
		this.graphicCard = graphicCard;
	}

	public Dell(){
		this.setType("dell笔记本");
	}

	public String toString() {
		return "型号:"+this.getType()+"\nCPU:"+this.getCpu()
				+"\n内存:"+this.getRam()+"\n硬盘:"+this.getHardDisk()
				+"\n操作系统:"+this.getOs();
	}
	
}


package model.create.build;
/**
 * @des  建造者模式所想创建的具体对象
 * @author felayman
 * @Time   下午4:50:50	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class Lenove extends Computer {
	private String graphicCard;
	
	public String getGraphicCard() {
		return graphicCard;
	}

	public void setGraphicCard(String graphicCard) {
		this.graphicCard = graphicCard;
	}

	public Lenove(){
		this.setType("联想笔记本");
	}

	public String toString() {
		return "型号:"+this.getType()+"\nCPU:"+this.getCpu()
				+"\n内存:"+this.getRam()+"\n硬盘:"+this.getHardDisk()
				+"\n显卡:"+this.getGraphicCard()+"\n操作系统:"+this.getOs();
	}
}



package model.create.build;
/**
 * @des  Dell电脑的生产组装线
 * @author felayman
 * @Time   下午5:05:17	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class DellBuilder implements ComputerBuilder{
	private Dell dell = new Dell();
	@Override
	public void buildCpu() {
		dell.setCpu("8核CPU");
	}

	@Override
	public void buildRam() {
		dell.setRam("8GB内存");
	}

	@Override
	public void buildHardDisk() {
		dell.setHardDisk("2T硬盘");
	}

	@Override
	public void buildGraphicCard() {
		dell.setGraphicCard("AMD显卡");
	}

	@Override
	public void buildMonitor() {
		dell.setMonitor("20英寸显示器");
	}

	@Override
	public void buildOS() {
		dell.setOs("window8操作系统");
	}

	@Override
	public Computer getResult() {
		return dell;
	}
	
}



package model.create.build;
/**
 * @des  Lenove电脑的生产组装线
 * @author felayman
 * @Time   下午5:05:17	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class LenoveBuilder implements ComputerBuilder{
	private Lenove lenove = new Lenove();
	public void buildCpu() {
		lenove.setCpu("8核CPU");
	}
	public void buildRam() {
		lenove.setRam("8GB内存");
	}

	@Override
	public void buildHardDisk() {
		lenove.setHardDisk("1T硬盘");
	}

	@Override
	public void buildGraphicCard() {
		lenove.setGraphicCard("Inter显卡");
	}

	@Override
	public void buildMonitor() {
	}

	@Override
	public void buildOS() {
		lenove.setOs("window7操作系统");
	}

	@Override
	public Computer getResult() {
		return lenove;
	}
	
}



package model.create.build;
/**
 * @des  负责生产电脑的组织者
 * @author felayman
 * @Time   下午5:05:32	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class ComputerDirector {
	ComputerBuilder builder;
	
	public Dell createDell(){
		builder =  new DellBuilder();
		builder.buildCpu();
		builder.buildGraphicCard();
		builder.buildHardDisk();
		builder.buildMonitor();
		builder.buildRam();
		builder.buildOS();
		return (Dell) builder.getResult();
	}
	public Lenove createLenove(){
		builder =  new LenoveBuilder();
		builder.buildCpu();
		builder.buildGraphicCard();
		builder.buildHardDisk();
		builder.buildMonitor();
		builder.buildRam();
		builder.buildOS();
		return  (Lenove) builder.getResult();
	}
}


package model.create.build;
/**
 * @des  测试类
 * @author felayman
 * @Time   下午5:11:35	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class ComputerTest {
	public static void main(String[] args) {
		ComputerDirector director = new ComputerDirector();
		Dell dell =  director.createDell();
		Lenove lenove =director.createLenove();
		System.out.println("**********Dell笔记本***********");
		System.out.println(dell);
		System.out.println("**********Lenove笔记本***********");
		System.out.println(lenove);
	}
}


3.4原型模式

package model.create.prototype;
/**
 * @des  邮件的实体类
 * @author felayman
 * @Time   下午6:33:43	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class Email implements Cloneable {
	private String reciever;
	private String subject;
	private String application;
	private String context;
	public Email(String subject, String context) {
		this.subject = subject;
		this.context = context;
	}
	private String tail;

	public String getReciever() {
		return reciever;
	}

	public void setReciever(String reciever) {
		this.reciever = reciever;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public String getApplication() {
		return application;
	}

	public void setApplication(String application) {
		this.application = application;
	}

	public String getContext() {
		return context;
	}

	public void setContext(String context) {
		this.context = context;
	}

	public String getTail() {
		return tail;
	}

	public void setTail(String tail) {
		this.tail = tail;
	}
	public Email clone(){
		Email email = null;
		try {
			email = (Email) super.clone();
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return email;
	}

}

package model.create.prototype;
import java.util.Random;
/**
 * @des  测试类
 * @author felayman
 * @Time   下午7:16:18	
 * @Email  <a href=mailto:felayman@163.com>felayman@163.com</a>
 */
public class ClientDemo {
	private static final int MAX_COUNT = 6;
	public static void main(String[] args) {
		int i = 0;
		Email email = new Email("某上商场51抽奖活动", "五一抽奖活动通知:凡在五一期间购买....");
		email.setTail("解释权归商场所有");
		while(i++<MAX_COUNT){
			Email cloneEmail = email.clone();
			cloneEmail.setApplication(getRandString(5)+"先生");
			cloneEmail.setReciever(getRandString(5)+"@"+getRandString(8)+".com");
			sendMail(cloneEmail);
		}
	}
	private static void sendMail(Email cloneEmail) {
		System.out.println("标题:"+cloneEmail.getSubject()+"\t收件人:"+cloneEmail.getReciever()+"\t发送成功");
	}
	public static String getRandString(int i) {
		String source = "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM";
		StringBuffer sb = new StringBuffer();
		Random rand = new Random();
		for (int j = 0; j < i; j++) {
			sb.append(source.charAt(rand.nextInt(source.length())));
		}
		return sb.toString();
	}
}