工厂模式和代理模式都是面向接口的,更灵活;模板方法是面向抽象类的;单例模式只能产生一个对象,它们的思想:
工厂模式:在工厂接口中声明要获取的类型的抽象方法,让工厂类继承该接口,并实现该方法,在方法中返回需要的类型,或者返回实现了某个接口的类对象:
interface Worker {// 工厂接口中要返回的类型
public void doWork(); // 让工作者去工作.
}
interface WorkerFactory {// 工厂接口
public Worker getWorker(); // 产生一个实现了Worker接口的具体类对象;
}
class StudentWorker implements Worker {
@Override
public void doWork() {// 接口中可以没有public,因为默认就是,但类中必须写出来,因为默认是default的,权限不一样
System.out.println("学生的工作就是学习,学习好了,就有钱挣!!");
}
}
class TeacherWorker implements Worker {
@Override
public void doWork() {
System.out.println("上好课,教好学, 就有工资拿...");
}
}
class StudentWorkerFactory implements WorkerFactory {
@Override
public Worker getWorker() { // 产生一个实现了Worker接口的具体类对象;
Worker w = new StudentWorker();
return w;
}
}
class TeacherWorkerFactory implements WorkerFactory {
@Override
public Worker getWorker() { // 产生一个实现了Worker接口的具体类对象;
Worker w = new TeacherWorker();
return w;
}
}
class FactoryTest {
public static void test(WorkerFactory wf) {
wf.getWorker().doWork();
}
public static void main(String[] args) {
// 求助于工厂, 让工厂自动生成对象...
WorkerFactory wf = null;
if (args[0].equals("1")) {
wf = new StudentWorkerFactory();
} else {
wf = new TeacherWorkerFactory();
}
test(wf);
}
}
代理模式:在代理类中的方法中创建被代理类的对象,并调用该对象的同名方法:
interface HouseRent {
public void rent();
}
class MrZhang implements HouseRent {
@Override
public void rent() {
System.out.println("这是结婚用的房子,很干净,请爱护,租金20000");
}
}
class LianJia implements HouseRent {
HouseRent mz = new MrZhang();
@Override
public void rent() {
System.out.println("开始代理, 请交费3000");
mz.rent();
}
}
class ProxyTest {
public static void main(String[] args) {
HouseRent hr = new LianJia();
hr.rent();
}
}
模板方法:
public abstract class Template {
public final void getTime() {
long start = System.currentTimeMillis();
code();
long end = System.currentTimeMillis();
System.out.println("共使用了" + (end - start) + "毫秒.");
}
public abstract void code();
}
class SubTemplate extends Template {
@Override
public void code() {
for (int i = 0; i < 100000; i++) {
System.out.print(i + " ");
}
System.out.println();
}
}
class SubTemplate2 extends Template {
@Override
public void code() {
for (int i = 0; i < 10000; i++) {
System.out.print(i + " ");
}
System.out.println();
}
}
class TemplateTest {
public static void main(String[] args) {
Template t = new SubTemplate(); // 能用多态的地方,尽量要用多态
t.getTime();
t = new SubTemplate2(); // 能用多态的地方,尽量要用多态
t.getTime();
}
}
单例模式:两种
public class Singleton {
// 单例模式 : 饿汉式
private static Singleton onlyInstance = new Singleton();
public static Singleton getInstance() {
return onlyInstance;
}
private Singleton() {
}
}
// 懒汉式
class Singleton2 {
// 2) 声明私有的静态的本类类型的引用变量, 不赋值
private static Singleton2 only;
// 3) 提供一个公共的静态方法,用来获取引用变量, 在第一次调用时创建对象,以后就不创建了...
public static Singleton2 getInstance() {
if (only == null) { // 只有第一次调用时,才创建对象
only = new Singleton2();
}
return only;
}
// 1) 私有化构造器
private Singleton2() {
}
}
策略设计模式:创建一个这样的方法——它的参数是接口类型(或者含有接口类型),方法内部的某个地方调用的是接口中的抽象方法,但在传递参数的时候,传递的是实现了该接口的实现类,这样的话,就可以根据传递的参数不同,而调用不同的实现类中重写了该接口的同名方法,从而达到不同的效果,示例:
public class ProxyTest {
public static void main(String[] args) {
String print = print(new MyImpl());
System.out.println(print);
}
public static String print(MyInterface mi) {
return mi.test();
}
}
interface MyInterface {
String test();
}
class MyImpl implements MyInterface {
@Override
public String test() {
return "Hello world!";
}
}
装饰者模式:指的是通过一个包装类去包装原有对象,从而对原有对象的方法进行修改。当我们需要扩展某个类的某个功能但又不能去修改该类的源代码时,或者不需要永久修改该方法(也就是说在某些地方要用修改后的方法,某些地方要用修改前的方法),这时我们就可以使用装饰者模式,创建一个包装类,包装要扩展或修改的类。
装饰者模式使用步骤:
①创建一个包装类,包装类要求要和被包装类有相同的接口或父类
②在包装类中创建一个有参数的构造器,并通过构造器将被包装类的实例传进来,不能提供无参构造器
③不需要修改的方法可以直接通过被包装的对象间接实现
④修改我们需要扩展或修改的方法
⑤我们在使用包装类时,需要用包装类将被包装类包装
装饰者模式举例:敏感字符的过滤
在以下的程序代码中,要想过滤敏感字符,需要先获取到前台传递来的字符,再对其进行过滤,而获取字符是通过HttpServletRequest的实例实现的,该类中有个getParameter方法,可以获取到前台传递过来的字符串,所以我们要想使获取到的字符串是过滤后的字符串需要修改getParameter()方法
public void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain)throws IOException, ServletException {
String info = request.getParameter("info");
if(info != null){
info = info.replace("共产党","***");
}
}