此文章部分来于网络,为了学习总结。java
介绍:从一个对象再建立另外一个对象,而不需知道任何细节。面试
一、两种表现形式数据库
(1)简单形式apache
(2)登记形式设计模式
这两种表现形式仅仅是原型模式的不一样实现。安全
二、俩种克隆方法网络
(1)浅复制ide
介绍:只克隆值传递的数据(好比基本数据类型、String),而不复制它所引用的对象,就是对其余对象的引用都指向原来的对象。 注意:可实现Cloneable接口。
(2)深复制学习
介绍:除了浅度克隆要克隆的值外,还负责克隆引用类型的数据,把要复制的对象所引用的对象都复制了一遍。 注意:采用字节流写入写出对象,全部对象必须实现Serializable。Thread和Socket对象必须设置transient,不予复制。
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Prototype implements Cloneable, Serializable{ @Override protected Object clone() throws CloneNotSupportedException { //浅克隆 // TODO Auto-generated method stub Prototype prototype = (Prototype) super.clone(); return prototype; } public Object deepClone(){ //深克隆 try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); return null; } } }
介绍:将重复的部分上升到父类。ui
举例:公司的面试题是相同的,只有应聘者的答案不一样,因此相同的问题在父类中表现,子类只用做记录答案。
public class TestPaper { public void testQuestion1(){ System.out.println("1 + 1 = "); System.out.println("答案是:" + answer()); } protected String answer(){ return ""; } } public class TestPaperA extends TestPaper { @Override protected String answer() { // TODO Auto-generated method stub return "2"; } } public class Client { public static void main(String[] args) { TestPaper testPagerA = new TestPaperA(); testPagerA.question(); } }
介绍:定义一个高层接口,使得子系统更容易使用。
介绍:将一个复杂对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。
举例:遇到多个构造器参数时考虑使用构建器,而不是重叠构造器模式或JavaBean模式调用setter方法。(静态工厂和构造器有个共同的局限性:它们不能很好地扩展大量的可选参数)
/** * 构建器模式 * @author alex * @date 2017年4月6日 */ public class A { private final int a; private final int b; private final int c; public static class A_son { private final int a; private final int b; private int c = 0; public A_son(int a, int b) { this.a = a; this.b = b; } public A_son c(int val) { c = val; return this; } public A build() { return new A(this); } } public A(A_son a_son) { a = a_son.a; b = a_son.b; c = a_son.c; } } A a = new A.A_son(12, 12).c(12).build(); //客户端调用
缺点:构建器模式可能比重叠构造器更加冗长,参数多时使用较好。若是构建器没有在最初使用,后期使用会有些难以控制,一般一开始就使用构建器。
优势:构建器比重叠构造器的客户端代码易读写。比JavaBean更安全。
举例:项目中可能须要访问多种类型的数据库,数据库访问与逻辑业务应该独立分开,只需在客户端建立工厂类。
介绍:将对象转换的逻辑判断转移到不一样状态的类中,来简化复杂的逻辑判断。若是逻辑判断很简单就不须要用此模式了。
abstract class State { public abstract void handle(Context context); } public class Context { private State state; public Context(State state) { this.state = state; } public void request() { state.handle(this); } public State getState() { System.out.println("当前状态: " + state.getClass().toString()); return state; } public void setState(State state) { this.state = state; getState(); } } public class ConcreteStateA extends State { @Override public void handle(Context context) { // TODO Auto-generated method stub context.setState(new ConcreteStateB()); // 建立下一个逻辑判断 } } public class ConcreteStateB extends State { @Override public void handle(Context context) { // TODO Auto-generated method stub context.setState(new ConcreteStateA()); } } public class Test { public static void main(String[] args) { Context context = new Context(new ConcreteStateA()); context.request(); context.request(); context.request(); } }
介绍:系统的数据和行为都正确,但接口不符时,使得一个原有对象与某个接口匹配。
举例:假如巴西队中有中国球员,防止语言间的差别,中国球员须要翻译来与团队交流。
介绍:捕获一个对象的内部状态,并在该对象以外保存这个状态。以后可恢复以前的状态。
public class Originator { private String state; public Memento createMemento() { return new Memento(state); } public void setMemento(Memento memento) { state = memento.getState(); } public void show() { System.out.println("state =" + state); } public String getState() { return state; } public void setState(String state) { this.state = state; } } public class Caretaker { private Memento memento; public Memento getMemento() { return memento; } public void setMemento(Memento memento) { this.memento = memento; } } public class Memento { private String state; public Memento(String state) { this.state = state; } public String getState() { return state; } public void setState(String state) { this.state = state; } } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Originator originator = new Originator(); originator.setState("on"); originator.show(); Caretaker caretaker = new Caretaker(); caretaker.setMemento(originator.createMemento()); originator.setState("asdasd"); originator.show(); originator.setMemento(caretaker.getMemento()); originator.show(); } }
缺点:易消耗内存。
介绍:将对象组合成树形结构来表示部分-总体,使部分与总体具备一致性。
public abstract class Component { protected String name; public Component(String name) { this.name = name; } public abstract void add(Component c); public abstract void remove(Component c); public abstract void display(int depth); } import org.apache.commons.lang.StringUtils; public class Leaf extends Component { public Leaf(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void add(Component c) { // TODO Auto-generated method stub System.out.println("Don't add component"); } @Override public void remove(Component c) { // TODO Auto-generated method stub System.out.println("Don't remove component"); } @Override public void display(int depth) { // TODO Auto-generated method stub System.out.println(StringUtils.repeat("-", depth) + name); } } import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; public class Composite extends Component { private List<Component> list = new ArrayList<Component>(); public Composite(String name) { super(name); // TODO Auto-generated constructor stub } @Override public void add(Component c) { // TODO Auto-generated method stub list.add(c); } @Override public void remove(Component c) { // TODO Auto-generated method stub list.remove(c); } @Override public void display(int depth) { // TODO Auto-generated method stub System.out.println(StringUtils.repeat("-", depth) + name); for (Component component : list) { component.display(depth + 2); } } } public class Test { public static void main(String[] args) { Composite root = new Composite("root"); root.add(new Leaf("Leaf A")); root.add(new Leaf("Leaf B")); Composite comp = new Composite("Composite X"); comp.add(new Leaf("Leaf XA")); comp.add(new Leaf("Leaf XB")); root.add(comp); Composite comp2 = new Composite("Composite Y"); root .add(comp2); root.display(1); } }
介绍:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示
/** * 迭代器抽象 * @author chenguyan * @date 2017年6月16日 */ public abstract class Iterator { public abstract Object first(); public abstract Object next(); public abstract boolean isDone(); public abstract Object currentItem(); } /** * 汇集抽象 * @author chenguyan * @date 2017年6月16日 */ public abstract class Aggregate { public abstract Iterator createIterator(); } /** * 具体汇集 * @author chenguyan * @date 2017年6月16日 */ public class ConcreteAggregate extends Aggregate { private List<Object> items = new ArrayList<Object>(); @Override public Iterator createIterator() { // TODO Auto-generated method stub return new ConcreteIterator(this); } public int count() { return items.size(); } public Object get(int index) { return items.get(index); } public void add(Object obj) { items.add(obj); } } /** * 具体迭代器 * @author chenguyan * @date 2017年6月16日 */ public class ConcreteIterator extends Iterator { private ConcreteAggregate concreteAggregate; private int current = 0; public ConcreteIterator(ConcreteAggregate concrete) { // TODO Auto-generated constructor stub this.concreteAggregate = concrete; } @Override public Object first() { // TODO Auto-generated method stub return concreteAggregate.get(0); } @Override public Object next() { // TODO Auto-generated method stub current++; if (current >= concreteAggregate.count()) { return null; } return concreteAggregate.get(current); } @Override public boolean isDone() { // TODO Auto-generated method stub return current > concreteAggregate.count() ? true : false; } @Override public Object currentItem() { // TODO Auto-generated method stub return concreteAggregate.get(current); } } /** * 客户端 * @author chenguyan * @date 2017年6月16日 */ public class Client { public static void main(String[] args) { ConcreteAggregate concrete = new ConcreteAggregate(); concrete.add("a"); concrete.add("b"); concrete.add("c"); concrete.add("d"); concrete.add("e"); Iterator ite = new ConcreteIterator(concrete); System.out.println(ite.first().toString()); while (!ite.isDone()) { Object item = ite.next(); System.out.println(item != null ? item.toString() : ""); } } }
为何会采用抽象类的方式来实现迭代器呢?由于能够有不一样的迭代顺序,从前向后、从后向前等,因此随意新增迭代器的实现类来达到迭代顺序的不一样,并且客户端修改部分较少。
介绍:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
/** * 双重锁定 * @date 2017年7月3日 */ public class Singleton { private static Singleton singleton; private static Object syncObj = new Object(); public static Singleton getInstance() { if (singleton == null) { synchronized (syncObj) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
介绍:按各自的功能进行分类,使他们能够独立运行。
举例:手机的品牌与软件都会存在不兼容的状况,这是由于手机厂商即作硬件又作软件,没有统一的标准。若是有一个统一的硬件厂商设计标准,手机厂商只负责软件,这样每一个手机厂商开发的软件就不存在不兼容的状况了。
十5、命令模式
介绍:将请求命令封装成对象,从而使你可用不一样的请求命令来操做对象。
/** * 命令 * @date 2017年8月11日 */ public abstract class Command { private Recipient recipient; public void setRecipient(Recipient recipient) { this.recipient = recipient; } public abstract void doing(); } /** * 烤菜命令 * @date 2017年8月11日 */ public class RoastVegetablesCommand extends Command { private Recipient recipient; @Override public void setRecipient(Recipient recipient) { // TODO Auto-generated method stub this.recipient = recipient; } @Override public void doing() { // TODO Auto-generated method stub System.out.println("正在烤菜"); } } /** * 烤肉命令 * @date 2017年8月11日 */ public class RoastMeatCommand extends Command { private Recipient recipient; @Override public void setRecipient(Recipient recipient) { // TODO Auto-generated method stub this.recipient = recipient; } @Override public void doing() { // TODO Auto-generated method stub System.out.println("正在执行烤肉"); } } /** * 接收人 * @date 2017年8月11日 */ public class Recipient { private String name; private String job; public Recipient(String name, String job) { this.name = name; this.job = job; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } } /** * 服务员 * @date 2017年8月11日 */ public class Waiter { private List<Command> commandList = new ArrayList<Command>(); public void addOrder(Command command) { if (!commandList.contains(command)) { commandList.add(command); } } public void notifyCommand() { for (Command command : commandList) { command.doing(); } } } public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Recipient recipient = new Recipient("大厨", "大厨"); Command roastMeatCommand = new RoastMeatCommand(); Command roastVegetablesCommand = new RoastVegetablesCommand(); roastMeatCommand.setRecipient(recipient); roastVegetablesCommand.setRecipient(recipient); Waiter waiter = new Waiter(); waiter.addOrder(roastMeatCommand); waiter.addOrder(roastVegetablesCommand); waiter.notifyCommand(); } }
介绍:若是两个类没必要彼此通讯,那么这两个类就不该当发生直接的相互做用。强调类之间的松耦合。
class Employee{ private int id; private String name; private int age; public Employee(){} public Employee(int id, String name, int age){ this.id = id; this.name = name; this.age = age; } private void setId(int id){ this.id = id; } private int judge(int id){ return this.id - id; } private String sayHalo(String name){ return "Halo" + name; } } public class PrivateTest{ public static void main(String[] args){ Employee em = new Employee(1, "Alex", 22); Class<?> emClass = em.getClass(); Method judgeMethod = emClass.getDeclaredMethod("judge", new Class[]{Integer.TYPE}); //获取声明的方法 judgeMethod.setAccessible(true); //使成员能够访问 Method[] allMethods = emClass.getDeclaredMethods(); //获取全部声明的方法 AccessibleObject.setAccessible(allMethods, true); judgeMethod.invoke(em, new Object[]{3}); //经过反射访问 //or... for(Method method : allMethods){ ... } } }