java的中的设计模式

12 篇文章 0 订阅
1 篇文章 0 订阅

本篇文章用来写学习中遇到的java设计模式

1.  模板方法设计模式

    在定义功能时,功能的一部分是确定的,但有一部分是不确定的,而确定的部分在使用不确定的部分,此时就将不确定的部分暴露出去,由该类的子类去完成。也就是说为了避免子类的重复代码,我们将那些可能实现不同的细节暴露出去,由子类进行重写。

 例如: 需求是  获取一个程序运行的时间 。 

 分析: 我们可以获取程序开始和结束的时间,相减即可。

package test;

abstract class GetTime{
	public final void getTime(){
		long start = System.currentTimeMillis();
		//具体的功能由子类实现
		runcode();
		
		long end = System.currentTimeMillis();
		System.out.println("毫秒:"+(end-start));
	}
	
	public abstract void runcode();
}
// 实现具体的功能
class SubTime extends GetTime{
	public  void runcode(){
	   for(int x=0; x<4000; x++){}
	}
}

public class  TemplateDemo{
	public static void main(String[] args) {
		SubTime gt = new SubTime();
		gt.getTime();
	}
}

 

总结: 即提取出公用的代码,而将那些可变的行为交由子类去实现。

 

2.  单例模式

保证一个类只有一个实例,设计一个公共的方法,返回该实例。

常见的单例实现模式有 饿汉式,懒汉式。

饿汉式举例如下

package test;
/**
 * 单例模式之----饿汉式,
 *  在类加载时就进行了初始化。
 *
 */
public class SingleDemo {
  private static final SingleDemo singleDemo =new SingleDemo();
  
  private SingleDemo() {}

  public static SingleDemo getInstance(){
	  return singleDemo ;
  }
}

上述实现模式的问题在于 单例产生的时机无法控制,假如该实例中存在一个静态变量,那么当访问该静态变量时,就会触发创建类的实例。对其改造如下:懒汉模式

懒汉式举例如下:

package test;
/**
 * 懒汉式
 * 	类加载时并没有初始化。延迟加载
 */
public class SingleDemo2 {
	// 将构造方法私有化,禁止通过new进行创建
  private SingleDemo2() {}
  
  private static SingleDemo2 singledemo2 = null;
  // 使用的时候才开始初始化该对象
  public static synchronized SingleDemo2 getInstance(){
	  if(singledemo2 ==null)
		  singledemo2=new SingleDemo2() ;
	  return singledemo2 ;
  }
}

上述实现模式同样存在问题,虽然在同步方法中并没有做什么耗时的操作,但是在高并发中,多个线程进入时仍需要判断锁,所以也存在性能问题。对于改造如下:

 public class StaticSingleton{
    private  StaticSingleton(){
	   System.out.println("Singleton is create");
	}
	private static class SingleHolder{
		private static StaticSingletoninstance=new StaticSingleton();
	}

	public static StaticSingleton getInstance(){
	  return SingleHolder.instance ;
	} 
 }
 

 当 StaticSingleton被初始化的时候,其内部的静态内部类是不会被初始化的,只有当访问到 getInstance时,才会触发内部类的初始化。 

3. 装饰设计模式

   当对一组对象自的功能进行增强时,就可以使用该模式进行问题的解决。   

 和继承一样,都能进行功能的扩展。

 假如有一个继承体系:

    Writer

         1-- TextWriter : 用于操作文本

         1 -- MediaWriter : 用于操作媒体

 如果想加入缓冲技术来提高效率,那么理论上我们可以通过继承来进行具体的功能的扩展。于是现有体系就变成:

    Writer

        1 -- TextWriter 

            1-- BufferedTextWriter :加入了缓冲技术的操作文本对象。

        1 -- MediaWriter

            1 -- BufferedMediaWriter :加入了缓冲技术的操作媒体对象。

慢慢的,以后随着功能的扩展,就会发现只为提高功能,而进行的继承,导致继承体系越来越臃肿,不够灵活。

  重新思考下:

    既然加入的是同一种技术,可不可以将缓冲技术进行单独的封装,哪个对象需要缓冲,就将哪个对象和缓冲关联。

   eg:

class BufferWriter{
	BufferWriter(Writer w)
	{
		直接对父类进行操作后,子类也跟着变化了 。
	}
}

  于是,现在继承体系就变为:

     Writer

  1--TextWriter :用于操作文本。

  1--MediaWriter:用于操作媒体。

  1--BufferWriter:用于提高效率。

   装饰比继承更为灵活, 但是需要  装饰类和被装饰类都必须所属同一个接口或父类。

4. 不变模式

   一个类的内部状态创建后,在整个生命周期间都不会发生改变时,就是不变类

不变模式时不需要同步的,并且不变模式不会被修改,即 仅仅是一个可读对象,并不需要同步,这样就提供了很高的性能。

public final class Product{
	// 确保无子类
	private final String no ;
	// 私有属性,不会被其他对象获取。
	private final String name ;
	// final 保证属性不会被2次赋值

//final 修饰变量的时候,可以先声明,而不给初值,这被称为final空白,无论什么情况下,编译器都确保空白final在使用之前必须被初始化
	private final double price ;

	public Product(String no,String name,double price){// 在创建对象时,必须指定数据
		super();
		   //因为创建之后,无法进行修改。
		this.no =no ;
		this.name=name ;
		this.price=price ;
	}
	// getter ,注意:不需要setter
}

  5. 生产者消费者模式

生产者消费者是一个经典的多线程设计模式。它为多线程的协作提供了良好的解决方案。在生产者-消费者模式中,通常有两类线程, 即若干个生产者线程和若干个消费者线程。生产者负责提交用户请求,消费者线程则负责具体处理生产者的提交的任务。生产者和消费者之间则通过共享内存缓冲区进行通信。 其实现见 Java多线程-生产者消费者问题  java多线程

 6. 代理模式

   代理模式就是说,给某个对象提供一个代理对象,由代理对象来控制原有对象自的行为,就如我们自己买票,由于抽不出空,所以提供信息给 售票贩子,让他们帮忙买。

   代理模式主要有两种,jdk代理和cglib代理,两种代理模式在实现上稍有不同。

 jdk代理 即实现   java.lang.reflect.InvocationHandler ,通过重写  invoke 即可。

public interface Person {
    // 寻找真爱
    void findLove();
   String getName();

   String getSex();
}
//     ......
public class PersonProxy implements InvocationHandler {
    private Person target;
    // 获取代理人的 信息
    public Object getInstance(Person target) throws Exception {
        this.target = target;
        Class clazz =target.getClass() ;
        return Proxy.newProxyInstance(clazz.getClassLoader(), target.getClass().getInterfaces(), this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("------ 代理类-------");
        this.target.findLove(); 
        return null;
    }
}

public class XiaoXingxing implements  Person {
    private  String sex = "女";
    private String name = "小星星";
    @Override
    public void findLove() {
        System.out.println("我叫: " +this.name +", 性别: " +this.sex+", 我的要求是:\n");
        System.out.println("长得帅的");
        System.out.println("有房有车的");
        System.out.println("身高180cm以上,体重60kg");
    }
// ........ 省略其他方法
}
// .....
public class TestFindLove {
    public static void main(String[] args) {
//        new XiaoXingxing().findLove();

        try {
           Person proxy= (Person)new PersonProxy ().getInstance(new XiaoXingxing());
           proxy.findLove();
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

 cglib代理如下:

public class YProxy implements MethodInterceptor {
    public Object getInstance(Object obj) throws  Exception{
        Enhancer enhancer=new Enhancer();
        //把父类设置为谁
        enhancer.setSuperclass(obj.getClass());
        enhancer.setCallback(this);
        //通过反射机制,给它实例化
        return  enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("代理模式" );
        methodProxy.invokeSuper(o,objects);
        return null;
    }
}
// ........
public class YunZJ {
    public void findLove(){
        System.out.println("肤白貌美大长腿");
    }
}
// ....
public class TestCglibProxy {
    public static void main(String[] args) {
        try {
            YunZJ obj = (YunZJ)new YProxy().getInstance(new YunZJ());
            obj.findLove();
        }catch ( Exception e ){}
    }
}

 7. 工厂模式

该模式旨在隐藏复杂的逻辑过程,只关心结果。主要有简单工厂、工厂方法、抽象工厂。

 简单工厂如下:

// 规定一定的标准
public interface Car {
    // 规定汽车的品牌
    String getName() ;
}
// ...
public class Benz implements  Car {
    @Override
    public String getName() {
        return "奔驰";
    }
}
public class BMW implements  Car {
    @Override
    public String getName() {
        return "宝马";
    }
}
public class SimpleFactory {
    // 实现统一管理,专业化管理,通过不同条件(品牌),返回对应的汽车
    public Car getCar(String name) {
        if ("BMW".equalsIgnoreCase(name)) {
            return new BMW();
        } else if ("BENZ".equalsIgnoreCase(name)) {
            return new Benz();
        } else {
            System.out.println("未有生产工艺");
            return null;
        }
    }
}

// 对于消费者而言,并不需要关心其中的细节,只关心返回的结果。
public class SimpleFactoryTest  {
    public static void main(String[] args) {
        // 消费者
        Car car = new SimpleFactory().getCar("BMW");
        System.out.println(car.getName());
    }
}

 工厂方法:

public interface Factory {
    Car getCar();
}
//... 直接由对应的工厂生产出产品
public class BenzFactory implements  Factory {
    @Override
    public Car getCar() {
        return new Benz();
    }
}
//***
public class BmwFactory implements  Factory {
    @Override
    public Car getCar() {
        return new BMW();
    }
}
//***
public class FactoryTest {
    public static void main(String[] args) {
        // 工厂方法模式
          //各个产品的生产商,都拥有各自的工厂,生产工艺,生成的高科技程度都是不一样的
        Factory factory = new BenzFactory();
        System.out.println(factory.getCar().getName());

        factory = new BmwFactory();
        System.out.println(factory.getCar().getName());
    }
}

 抽象工厂:

public abstract class AbstractFactory {
    abstract Car getCar();

    public Car getCar(String name) {
        if ("BMW".equalsIgnoreCase(name)) {
            return new BmwFactory().getCar();
        } else if ("BENZ".equalsIgnoreCase(name)) {
            return new BenzFactory().getCar();
        } else {
            System.out.println("未有生产工艺");
            return null;
        }
    }
}
//***
public class BenzFactory extends AbstractFactory {
    @Override
    public Car getCar() {
        return new Benz();
    }
}
//***
public class BmwFactory extends AbstractFactory {
    @Override
    public Car getCar() {
        return new BaoMa();
    }
}
//***
public class DefaultFactory extends AbstractFactory {
    private BenzFactory defaultFactory = new BenzFactory();

    @Override
    public Car getCar() {
        return defaultFactory.getCar();
    }
}
//*** 
public class AbstractFactoryTest {
    public static void main(String[] args) {
        DefaultFactory factory = new DefaultFactory();
        System.out.println(factory.getCar().getName());

//        factory=new DefaultFactory().ge;
        System.out.println(factory.getCar("BMW").getName());
    }
}

未完待续    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值