简单工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class FoodFactory { public static Food makeFood(String name) { if (name.equals("noodle")) { Food noodle = new LanZhouNoodle(); noodle.addSpicy("more"); return noodle; } else if (name.equals("chicken")) { Food chicken = new HuangMenChicken(); chicken.addCondiment("potato"); return chicken; } else { return null; } } }
|
工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public interface FoodFactory { Food makeFood(String name); } public class ChineseFoodFactory implements FoodFactory {
@Override public Food makeFood(String name) { if (name.equals("A")) { return new ChineseFoodA(); } else if (name.equals("B")) { return new ChineseFoodB(); } else { return null; } } } public class AmericanFoodFactory implements FoodFactory {
@Override public Food makeFood(String name) { if (name.equals("A")) { return new AmericanFoodA(); } else if (name.equals("B")) { return new AmericanFoodB(); } else { return null; } } }
|
抽象工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void main(String[] args) { ComputerFactory cf = new AmdFactory(); CPU cpu = cf.makeCPU(); MainBoard board = cf.makeMainBoard(); HardDisk hardDisk = cf.makeHardDisk(); Computer result = new Computer(cpu, board, hardDisk); }
|
单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public class Singleton { private Singleton() {}; private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } public static Date getDate(String mode) {return new Date();} }
public class Singleton { private Singleton() {} private static volatile Singleton instance = null;
public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
public class Singleton3 {
private Singleton3() {} private static class Holder { private static Singleton3 instance = new Singleton3(); } public static Singleton3 getInstance() { return Holder.instance; } }
public enum Singleton4 { INSTANCE; public void whateverMethod() {} }
|
建造者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| class User { private String name; private String password; private String nickName; private int age;
private User(String name, String password, String nickName, int age) { this.name = name; this.password = password; this.nickName = nickName; this.age = age; } public static UserBuilder builder() { return new UserBuilder(); } public static class UserBuilder { private String name; private String password; private String nickName; private int age;
private UserBuilder() { }
public UserBuilder name(String name) { this.name = name; return this; }
public UserBuilder password(String password) { this.password = password; return this; }
public UserBuilder nickName(String nickName) { this.nickName = nickName; return this; }
public UserBuilder age(int age) { this.age = age; return this; }
public User build() { if (name == null || password == null) { throw new RuntimeException("用户名和密码必填"); } if (age <= 0 || age >= 150) { throw new RuntimeException("年龄不合法"); } if (nickName == null) { nickName = name; } return new User(name, password, nickName, age); } } }
|
原型模式
原型模式很简单:有一个原型实例,基于这个原型实例产生新的实例,也就是“克隆”了。
Object 类中有一个 clone() 方法,它用于生成一个新的对象,当然,如果我们要调用这个方法,java 要求我们的类必须先实现 Cloneable 接口,此接口没有定义任何方法,但是不这么做的话,在 clone() 的时候,会抛出 CloneNotSupportedException 异常。
代理模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public interface FoodService { Food makeChicken(); Food makeNoodle(); }
public class FoodServiceImpl implements FoodService { public Food makeChicken() { Food f = new Chicken() f.setChicken("1kg"); f.setSpicy("1g"); f.setSalt("3g"); return f; } public Food makeNoodle() { Food f = new Noodle(); f.setNoodle("500g"); f.setSalt("5g"); return f; } }
public class FoodServiceProxy implements FoodService { private FoodService foodService = new FoodServiceImpl(); public Food makeChicken() { System.out.println("我们马上要开始制作鸡肉了"); Food food = foodService.makeChicken(); System.out.println("鸡肉制作完成啦,加点胡椒粉"); food.addCondiment("pepper"); return food; } public Food makeNoodle() { System.out.println("准备制作拉面~"); Food food = foodService.makeNoodle(); System.out.println("制作完成啦") return food; } }
|
代理模式就是做“方法包装”或做“方法增强”。在面向切面编程中,其实就是动态代理的过程。比如Spring中,自己不需要定义代理类,但是Spring会帮我们动态来定义代理,然后把我们定义在@Before、@After、@Around中的代码逻辑动态添加到代理中。
Spring中实现动态代理有两种,一种是如果我们的类定义了接口,如UserService接口和UserServiceImpl实现类,那么采用 JDK 的动态代理,感兴趣的读者可以去看看 java.lang.reflect.Proxy 类的源码;另一种是我们自己没有定义接口的,Spring 会采用 CGLIB 进行动态代理,它是一个 jar 包,性能还不错。
适配器模式
适配器模式就是,有一个接口需要实现,但是我们现成的对象都不满足,需要加一层适配器来进行适配。适配器模式总体来说分三种:默认适配器模式、对象适配器模式、类适配器模式。
默认适配器模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| public interface FileAlterationListener { void onStart(final FileAlterationObserver observer); void onDirectoryCreate(final File directory); void onDirectoryChange(final File directory); void onDirectoryDelete(final File directory); void onFileCreate(final File file); void onFileChange(final File file); void onFileDelete(final File file); void onStop(final FileAlterationObserver observer); }
public class FileAlterationListenerAdaptor implements FileAlterationListener {
public void onStart(final FileAlterationObserver observer) { }
public void onDirectoryCreate(final File directory) { }
public void onDirectoryChange(final File directory) { }
public void onDirectoryDelete(final File directory) { }
public void onFileCreate(final File file) { }
public void onFileChange(final File file) { }
public void onFileDelete(final File file) { }
public void onStop(final FileAlterationObserver observer) { } }
public class FileMonitor extends FileAlterationListenerAdaptor { public void onFileCreate(final File file) { doSomething(); }
public void onFileDelete(final File file) { doSomething(); } }
|
对象适配器模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| public interface Duck { public void quack(); public void fly(); }
public interface Cock { public void gobble(); public void fly(); }
public class WildCock implements Cock { public void gobble() { System.out.println("咕咕叫"); } public void fly() { System.out.println("鸡也会飞哦"); } }
public class CockAdapter implements Duck { Cock cock; public CockAdapter(Cock cock) { this.cock = cock; } @Override public void quack() { cock.gobble(); } @Override public void fly() { cock.fly(); } }
public static void main(String[] args) { Cock wildCock = new WildCock(); Duck duck = new CockAdapter(wildCock); ... }
|
类适配器
通过继承的方法,适配器自动获得了所需要的大部分方法。
总结
- 类适配和对象适配的异同
- 一个采用继承、一个采用组合
- 类适配器属于静态实现,对象适配器属于组合的动态实现,对象适配器需要多实例化一个对象
适配器模式 VS 代理模式
对象适配器模式和代理模式,在代码结构上,它们很相似,都需要一个具体的实现类的实例。但是它们的目的不一样,代理模式做的是增强原方法的活;适配器做的是适配的活,为的是提供“把鸡包装成鸭,然后当做鸭来使用”,而鸡和鸭它们之间原本没有继承关系。
桥梁模式
通过两个抽象类之间的引用,来达到子类之间的相互引用。
装饰器模式
对类做增强,而不是对方法做增强
门面模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class ShapeMaker { private Shape circle; private Shape rectangle; private Shape square;
public ShapeMaker() { circle = new Circle(); rectangle = new Rectangle(); square = new Square(); }
public void drawCircle(){ circle.draw(); } public void drawRectangle(){ rectangle.draw(); } public void drawSquare(){ square.draw(); } }
public static void main(String[] args) { ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle(); shapeMaker.drawRectangle(); shapeMaker.drawSquare(); }
|
组合模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class Employee { private String name; private String dept; private int salary; private List<Employee> subordinates;
public Employee(String name,String dept, int sal) { this.name = name; this.dept = dept; this.salary = sal; subordinates = new ArrayList<Employee>(); }
public void add(Employee e) { subordinates.add(e); }
public void remove(Employee e) { subordinates.remove(e); }
public List<Employee> getSubordinates(){ return subordinates; }
public String toString(){ return ("Employee :[ Name : " + name + ", dept : " + dept + ", salary :" + salary+" ]"); } }
|
享元模式
享元分开来说就是 共享 元器件,也就是复用已经生成的对象,这种做法当然也就是轻量级的了。复用对象最简单的方式是,用一个 HashMap 来存放每次新生成的对象。每次需要一个对象的时候,先到 HashMap 中看看有没有,如果没有,再生成新的对象,然后将这个对象放入 HashMap 中。
策略模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public interface Strategy { public void draw(int radius, int x, int y); }
public class RedPen implements Strategy { @Override public void draw(int radius, int x, int y) { System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } } public class GreenPen implements Strategy { @Override public void draw(int radius, int x, int y) { System.out.println("用绿色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } } public class BluePen implements Strategy { @Override public void draw(int radius, int x, int y) { System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y); } }
public class Context { private Strategy strategy;
public Context(Strategy strategy){ this.strategy = strategy; }
public int executeDraw(int radius, int x, int y){ return strategy.draw(radius, x, y); } }
|
和桥梁模式很相似,桥梁模式多加了一层抽象,桥梁模式耦合更低,结构更复杂。
观察者模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; public int getState() { return state; } public void setState(int state) { this.state = state; notifyAllObservers(); } public void attach(Observer observer) { observers.add(observer); } public void notifyAllObservers() { for (Observer observer : observers) { observer.update(); } } }
public abstract class Observer { protected Subject subject; public abstract void update(); }
public class BinaryObserver extends Observer { public BinaryObserver(Subject subject) { this.subject = subject; this.subject.attach(this); } @Override public void update() { String result = Integer.toBinaryString(subject.getState()); System.out.println("订阅的数据发生变化,新的数据处理为二进制值为:" + result); } }
public class HexaObserver extends Observer { public HexaObserver(Subject subject) { this.subject = subject; this.subject.attach(this); } @Override public void update() { String result = Integer.toHexString(subject.getState()).toUpperCase(); System.out.println("订阅的数据发生变化,新的数据处理为十六进制值为:" + result); } }
|
责任链模式
模版方法模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public abstract class AbstractTemplate { public void templateMethod() { init(); apply(); end(); }
protected void init() { System.out.println("init 抽象层已经实现,子类也可以选择覆写"); }
protected abstract void apply();
protected void end() { } }
public class ConcreteTemplate extends AbstractTemplate { public void apply() { System.out.println("子类实现抽象方法 apply"); }
public void end() { System.out.println("我们可以把 method3 当做钩子方法来使用,需要的时候覆写就可以了"); } }
|
状态模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public interface State { public void doAction(Context context); }
public class DeductState implements State {
public void doAction(Context context) { System.out.println("商品卖出,准备减库存"); context.setState(this);
}
public String toString() { return "Deduct State"; } }
public class RevertState implements State { public void doAction(Context context) { System.out.println("给此商品补库存"); context.setState(this);
}
public String toString() { return "Revert State"; } }
public class Context { private State state; private String name; public Context(String name) { this.name = name; } public void setState(State state) { this.state = state; } public void getState() { return this.state; } }
public static void main(String[] args) { Context context = new Context("iPhone X"); State revertState = new RevertState(); revertState.doAction(context); State deductState = new DeductState(); deductState.doAction(context); }
|