- 设计模式:
- 单例模式:
应用场景:如果希望在系统中某个类的实例只存在一个,并且提供一个访问他的全 局访问点。
写法:
饿汉单例(在类加载的时候就完成了初始化,所以类加载比较慢,但是获取对象的速度很快):
public class Singleton {
//饿汉单例模式
//在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快
private static Singleton instance = new Singleton();//静态私有成员,已初始化
private Singleton()
{
//私有构造函数
}
public static Singleton getInstance() //静态,不用同步(类加载时已初始化,不会有多线程的问题)
{
return instance;
}
}
懒汉式:
package leecodeTest;
public class Singleton {
//懒汉式单例模式
//比较懒,在类加载时,不创建实例,因此类加载速度快,但运行时获取对象的速度慢
private static Singleton intance = null;//静态私用成员,没有初始化
private Singleton()
{
//私有构造函数
}
public static synchronized Singleton getInstance() //静态,同步,公开访问点
{
if(intance == null)
{
intance = new Singleton();
}
return intance;
}
}
-
- 工厂设计模式
普通工厂模式(通过建立一个工厂类,对实现同一接口的一些类进行实例的创 建):
public interface Sender {
void send();
}
public class MailSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is mail sender...");
}
}
public class SmsSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is sms sender...");
}
}
public class FactoryPattern {
public static void main(String[] args) {
Sender sender=produce("mail");
sender.send();
}
public static Sender produce(String str) {
if ("main".equals(str)) {
return new MailSender();
}else if ("sms".equals(str)) {
return new SmsSender();
} else {
System.out.println("输入错误...");
return null;
}
}
}
多个工厂方法模式(对普通工厂方法进行改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确的创建对象,而多个工厂方法模式提供多个工厂方法,分别创建对象):
public interface Sender {
void send();
}
public class MailSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is mail sender...");
}
}
public class SmsSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is sms sender...");
}
}
public class SendFactory {
public Sender produceMail() {
return new MailSender();
}
public Sender produceSms() {
return new SmsSender();
}
}
public class FactoryPattern {
public static void main(String[] args) {
SendFactory sendFactory=new SendFactory();
Sender sender=sendFactory.produceMail();
sender.send();
}
}
静态工厂模式:
public interface Sender {
void send();
}
public class MailSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is mail sender...");
}
}
public class SmsSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is sms sender...");
}
}
public class SendFactory {
public static Sender produceMail() {
return new MailSender();
}
public static Sender produceSms() {
return new SmsSender();
}
}
public static void main(String[] args) {
Sender sender=SendFactory.produceMail();
sender.send();
}
抽象工厂模式:工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说如果想扩展程序,必须对工厂类进行修改,这就违背了闭包原则,所以从设计角度考虑,有一定的问题。那么我们就用到了抽象工厂模式,创建多个工厂类,这样一点需要增加新的功能,直接添加新的工厂类就可以,不需要修改之前的代码。
public interface Provider {
Sender produce();
}
public interface Sender {
void send();
}
public class SmsSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is sms sender...");
}
}
public class MailSender implements Sender{
@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("This is mail sender...");
}
}
public class SendMailFactory implements Provider{
@Override
public Sender produce() {
// TODO Auto-generated method stub
return new MailSender();
}
}
public class SendSmsFactory implements Provider {
@Override
public Sender produce() {
// TODO Auto-generated method stub
return new SmsSender();
}
}
public class FactoryPattern {
public static void main(String[] args) {
//调用provide接口的实现方法得到一个SendMailFactory对象
Provider provider=new SendMailFactory();
//调用SendMailFactory里面的方法获取到MailSender对象
Sender sender=provider.produce();
sender.send();
}
}
建造者模式(工厂模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来管理,用来创建复合对象,所谓复合对象就是指某个类中有不同的属性):
//抽象接口
public abstract class Builder {
//第一步:装CPU
public abstract void buildCPU();
//第二部:装主板
public abstract void buildMainBoard();
//第三部:装硬盘
public abstract void buildHD();
//获得组装好的电脑
public abstract Computer getComputer();
}
/*
* 实现Builder接口已构造和装配改产品的各个部件
* */
//具体装机人员
public class ConcreateBuilder extends Builder{
Computer computer=new Computer();
@Override
public void buildCPU() {
// TODO Auto-generated method stub
computer.add("装CPU");
}
@Override
public void buildMainBoard() {
// TODO Auto-generated method stub
computer.add("装主板");
}
@Override
public void buildHD() {
// TODO Auto-generated method stub
computer.add("装硬盘");
}
@Override
public Computer getComputer() {
// TODO Auto-generated method stub
return computer;
}
}
//构造复杂对象。ConcreateBuilder创建该产品的内部表示并定义他的装配过程
public class Computer {
//电脑组件组合
private List<String> parts=new ArrayList<>();
public void add(String part) {
parts.add(part);
}
public void print() {
for(int i=0;i<parts.size();i++) {
System.out.println("组件"+parts.get(i)+"装好了");
}
System.out.println("电脑组装完毕……");
}
}
//构造一个使用builder接口的对象
//装机人员装机
public class Director {
public void Construct(Builder builder) {
builder.buildCPU();
builder.buildMainBoard();
builder.buildHD();
}
}
public class BuilderPattern {
public static void main(String[] args) {
Director director=new Director();
Builder builder=new ConcreateBuilder();
director.Construct(builder);
Computer computer=builder.getComputer();
computer.print();
}
}
-
- 适配器设计模式(适配器模式是将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的了的兼容性问题。主要分为:类的适配器模式,对象的适配器模式,接口的适配器模式):
类的适配器模式:
public class Source {
public void method1() {
System.out.println("this is original method---");
}
}
public interface Targetable {
/*
* 与原类中的方法相同
* */
public void method1();
/*
* 新类的方法
* */
public void method2();
}
public class Adapter extends Source implements Targetable{
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("this is the targetable method---");
}
}
public class AdaptPattern {
public static void main(String[] args) {
Targetable targetable=new Adapter();
targetable.method1();
targetable.method2();
}
}
对象的适配器模式(基本思路和类的适配器模式相同,只是将Adapter类作修改,这次不继承Source类,而是持有Source类的实例,已达到解决兼容性问题):
public class Source {
public void method1() {
System.out.println("this is original method---");
}
}
public interface Targetable {
/*
* 与原类中的方法相同
* */
public void method1();
/*
* 新类的方法
* */
public void method2();
}
public class Wrapper implements Targetable{
private Source source;
public Wrapper(Source source) {
this.source=source;
}
@Override
public void method1() {
// TODO Auto-generated method stub
source.method1();
}
@Override
public void method2() {
// TODO Auto-generated method stub
System.out.println("this is the targetable method---");
}
}
public class AdaptPattern {
public static void main(String[] args) {
Source source=new Source();
Targetable targetable=new Wrapper(source);
targetable.method1();
targetable.method2();
}
}
接口的适配器模式(有时候我们一个接口中有很多抽象方法,当我们去写改接口的实现类时,必须实现该接口中的所有方法,这明显有时比较浪费,因为不是每个方法都是我们需要的,有时只需要某一些,因此我们引用接口的适配器模式,借助一个抽象类,该抽象类实现了该接口,实现了所有方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们要写一个类,继承该抽象类,重写我们需要的方法就行):
理解:通过一个抽象类实现一个接口,重写里面的所有的方法,如果我们需要使用其中的某些方法,需要另外建立另一个类继承这个抽象方法,然后重写你需要的那个方法
//定义端口,提供通信服务
public interface Port {
//远程SSH端口为22
void SSH();
//网络端口为80
void NET();
//Tomcat容器端口为8080
void Tomcat();
//mysql数据库端口为3306
void MySQL();
}
//定义抽象类实现端口接口,但是什么事情都不做
public abstract class Wrapper implements Port{
@Override
public void SSH() {
// TODO Auto-generated method stub
}
@Override
public void NET() {
// TODO Auto-generated method stub
}
@Override
public void Tomcat() {
// TODO Auto-generated method stub
}
@Override
public void MySQL() {
// TODO Auto-generated method stub
}
}
//提供聊天服务
//需要网络功能
public class Chat extends Wrapper{
@Override
public void NET() {
// TODO Auto-generated method stub
System.out.println("hello world");
}
}
//网站服务器
//需要tomcat服务器,Mysql数据库,网络服务,远程服务
public class Server extends Wrapper{
@Override
public void SSH() {
// TODO Auto-generated method stub
System.out.println("Connect success---");
}
@Override
public void NET() {
System.out.println("WWW---");
}
@Override
public void Tomcat() {
// TODO Auto-generated method stub
System.out.println("Tomcat is running---");
}
@Override
public void MySQL() {
// TODO Auto-generated method stub
System.out.println("Mysql is running---");
}
}
-
- 装饰者模式(顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰者对象和被装饰者对象实现同一个接口,装饰者对象持有被装饰对象的实例):
-
public interface Shape { void draw(); } public class Rectangle implements Shape { @Override public void draw() { // TODO Auto-generated method stub System.out.println("Shape: Rectangle"); } } public class Circle implements Shape{ @Override public void draw() { // TODO Auto-generated method stub System.out.println("Shape: Circle..."); } } //创建实现了Shape接口的抽象装饰类 public abstract class ShapeDecorator implements Shape{ protected Shape decoratedShape; public ShapeDecorator(Shape decoratedShape) { this.decoratedShape=decoratedShape; } @Override public void draw() { // TODO Auto-generated method stub decoratedShape.draw(); } } //创建扩展自ShapeDecorator类的实体装饰类 public class RedShapeDecorator extends ShapeDecorator{ public RedShapeDecorator(Shape decoratedShape) { // TODO Auto-generated constructor stub super(decoratedShape); } @Override public void draw() { // TODO Auto-generated method stub decoratedShape.draw(); setRedBorder(decoratedShape); } private void setRedBorder(Shape decoratedShape) { System.out.println("Border Color: Red"); } } public class DecoratorPattern { public static void main(String[] args) { Shape circle=new Circle(); Shape redCircle=new RedShapeDecorator(new Circle()); Shape redRectangle=new RedShapeDecorator(new Rectangle()); System.out.println("Circle with normal border"); circle.draw(); System.out.println("\nCircle of red border"); redCircle.draw(); System.out.println("\nRectangle of red border"); redRectangle.draw(); } }
-
- 策略模式(策略模式定义了一系列算法,并将每个算法包装起来,使他们可以互相替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现改接口,设计一个抽象类(可有可无)属于辅助类。策略模式的决定权在于用户,系统本身提供不同算法的实现,新增或者删除算法,对各种算法做封装。因此策略模式多用于在算法决策系统中,外部用户只需要决定用哪个算法就可以):
-
public class ConcreteStrategyA extends Stategy{ //算法A的实现方法 @Override public void AlgorithmInterface() { // TODO Auto-generated method stub System.out.println("算法A的实现"); } } public class ConcreteStrategyB extends Stategy{ @Override public void AlgorithmInterface() { // TODO Auto-generated method stub System.out.println("算法B的实现"); } } public class ConcreteStrategyC extends Stategy{ @Override public void AlgorithmInterface() { // TODO Auto-generated method stub System.out.println("算法C的实现"); } } //抽象算法的策略类,定义所有支持的算法的公共接口 public abstract class Stategy { //算法方法 public abstract void AlgorithmInterface(); } public class Context { Stategy stategy; public Context(Stategy stategy) { this.stategy=stategy; } public void contextInterface() { stategy.AlgorithmInterface(); } } public class StrategyPattern { public static void main(String[] args) { Context context; context=new Context(new ConcreteStrategyA()); context.contextInterface(); context=new Context(new ConcreteStrategyB()); context.contextInterface(); context=new Context(new ConcreteStrategyC()); context.contextInterface(); } }
-
- 代理模式(代理模式指给对象提供一个代理对象,并由代理对象控制对原对象的引用。代理可以分为动态代理和静态代理。通过代理模式,可以利用代理对象为被代理对象添加额外的功能,以此来拓展被代理对象的功能。可以用于计算某个方法执行的时间,在执行方法前后记录日志等操作):
①静态代理(静态代理需要我们写出代理类和被代理类,而且一个代理类和被代理类一一对应。代理类和被代理类需要实现同一个接口,通过聚合使得代理对象中有被代理对象的引用,以此实现代理对象控制被代理对象的目的)
//共同实现的接口
public interface IService {
void service();
}
//被代理类
public class Service implements IService{
@Override
public void service() {
// TODO Auto-generated method stub
System.out.println("被代理对象执行相关操作");
}
}
//代理类
public class ProxyService implements IService{
//持有被代理对象的引用
private IService service;
//默认代理Service类
public ProxyService() {
this.service=new Service();
}
//也可以代理实现相同接口的其他类
public ProxyService(IService service) {
this.service = service;
}
@Override
public void service() {
// TODO Auto-generated method stub
System.out.println("开始执行service()方法");
service.service();
System.out.println("service()方法执行完毕");
}
}
//测试了
public class ProxyPattern {
public static void main(String[] args) {
IService service=new Service();
//传入被代理的对象
ProxyService proxyService=new ProxyService(service);
proxyService.service();
}
}
1)
②动态代理(jdk1.3之后,java通过java,lang,reflect包中的三个类Proxy,InvocationHandler,Method来支持动态代理。动态代理常用于有若干个代理对象,且为每个被代理对象添加的功能是相同的(例如在每个方法运行前后记录日志)。)
1)动态代理的代理类不需要我们自己编写,由java自动产生代理类源代码并进行编译最后生成代理对象。
2)创建动态代理的步骤:
a.指明一系列的接口来创建一个代理对象
b.创建一个调用处理器(InvocationHandler)对象
c.将这个代理指定为某个其他对象的代理对象
d.在调用处理器的invoke()方法获取代理,一方面将调用传递给真实对象,另一方执行各种需要的操作。
public interface IService {
void service();
}
//被代理类
public class Service implements IService{
@Override
public void service() {
// TODO Auto-generated method stub
System.out.println("被代理对象执行相关操作");
}
}
public class ServiceInvocationHandler implements InvocationHandler{
//被代理的对象
private Object srcObject;
public ServiceInvocationHandler(Object srcObject) {
this.srcObject=srcObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始执行"+method.getName()+"方法");
//执行原对象的相关操作
Object returnObj=method.invoke(srcObject, args);
System.out.println(method.getName()+"方法执行完毕");
return returnObj;
}
}
public class ProxyPattern {
public static void main(String[] args) {
IService service=new Service();
Class<? extends IService> clazz=service.getClass();
IService proxyService=(IService) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new ServiceInvocationHandler(service));
proxyService.service();
}
}