目录
工厂模式
1.工厂模式是解决创建对象实例化问题,让对象的创建依赖于工厂,我们无需关注创建对象的细节
在写工厂模式的时候尽量遵循 开闭原则(依赖接口实现一个创建工厂) 和单一职责原则(一个类做一件事情)。
public interface Person { public String getPerson(String sex); }
创建一个创建人类的工厂
public class PersonFactory implements Person{ @Override public String getPerson(String sex) { if ("男".equals(sex)) { return "男人"; } else if ("女".equals(sex)) { return "女人"; } return null; } }
public class singleTest { public static void main(String[] args) { PersonFactory personFactory = new PersonFactory(); String man = personFactory.getPerson("男"); System.out.println(man); } }
以上就是工厂模式的代码了
策略模式
策略模式,当我们做一件事情有很多种方法的时候,我们可以将每一种封装起来,根据不同的情况选择不同的方法。
比如我们做菜 有清真,白灼,我们可以把这些做菜的方式存储起来,当我们想用的时候直接调用就行了
创建一个做菜的接口
public interface Cook { //做菜 public String doCook(); }
我们去实现这个接口
public class Boiled implements Cook{ @Override public String doCook() { return "白灼"; } }
public class Muslim implements Cook{ @Override public String doCook() { return "清真"; } }
public enum SortStrategy { Boiled, Muslim }
再将每种做菜的方法封装起来,供我们选择
public class DoCook implements Cook{ private Cook cook; DoCook(SortStrategy sortStrategy) { setCook(sortStrategy); } @Override public String doCook() { return cook.doCook(); } public void setCook(SortStrategy sortStrategy) { switch (sortStrategy) { case Boiled: cook = new Boiled(); break; case Muslim: cook = new Muslim(); break; default: throw new IllegalArgumentException("error"); } } }
最后使用
public class stategyTest { public static void main(String[] args) { DoCook doCook = new DoCook(SortStrategy.Boiled); System.out.println(doCook.doCook()); } }
好了,这个就是策略模式了,我会继续更新设计模式的
单例模式
单例模式和工厂模式很相似,但是又有不同,单例模式是为了避免对象不重复创建,工厂模式是为了更加方便的创建对象,或者生成数据,不用关注创建对象的实现细节
具体实现有懒汉式,主要是指,不用每次都去创建对象,用到的时候才去创建对象
public class SingletonOne { public static SingletonOne singletonOne; /** * 懒汉式 */ private SingletonOne() { } public static SingletonOne getInstance() { if (singletonOne == null) { singletonOne = new SingletonOne(); } return singletonOne; } }
上面这个是线程不安全的,如果是多线程的情况下,回出问题,比如多个线程同时创建对象,并且赋值,那么先一步创建的对象就被覆盖了,没有指针所指向的内存地址了
public class SingletonTwo { public static volatile SingletonTwo singletonTwo; /** * 懒汉式 */ private SingletonTwo() { } public static SingletonTwo getInstance() { if (singletonTwo == null) { synchronized (SingletonTwo.class) { if (singletonTwo == null) { singletonTwo = new SingletonTwo(); } } } return singletonTwo; } }
这里加 volatile 是为了防止重排序,以防止读取到正在操作的内存对象比如一个线程正在执行创建对象,另一个对象走到synchronized (SingletonTwo.class),等对象创建成功后会又去创建一个对象
饿汉式,迫不及待的着急想要创建对象,先创建了一个对象,等来使用的时候直接拿就行,这样会有一个问题,那就是比较消耗内存
public class SingletonThree { public static SingletonThree singletonThree = new SingletonThree(); /** * 懒汉式 */ private SingletonThree() { } public static SingletonThree getInstance() { return singletonThree; } }
类部类的方式比较好一点,因为只有去使用的时候才会去创建
public class SingletonFour { /** * 懒汉式 */ private SingletonFour() { } public static SingletonFour getInstance() { return getSingletonHolder.singletonThree; } public static class getSingletonHolder { public static SingletonFour singletonThree = new SingletonFour(); } }
代理模式
代理模式主要是,把具体的实现和细节交给代理类,由代理类来完成
public interface CarInterface {
public void run();
public void stop();
}
public class CarProxy implements CarInterface{
private CarServiceImpl carService;
public CarProxy (CarServiceImpl carService) {
this.carService = carService;
}
@Override
public void run() {
System.out.println("代理模式");
carService.run();
}
@Override
public void stop() {
System.out.println("代理模式");
carService.stop();
}
}
public class CarProxyTest {
public static void main(String[] args) {
CarServiceImpl carService = new CarServiceImpl();
CarProxy carProxy = new CarProxy(carService);
carProxy.run();
carProxy.stop();
}
}
下面是动态代理,动态的对类进行增强
public class CarDoProxy implements InvocationHandler {
private CarServiceImpl carService;
public CarInterface getInstance(CarServiceImpl carService) {
this.carService = carService;
return (CarInterface) Proxy.newProxyInstance(carService.getClass().getClassLoader(), carService.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if (method.getName().equals("run")) {
System.out.println("开始执行 run");
result = method.invoke(carService);
} else if (method.getName().equals("stop")) {
System.out.println("开始执行 stop");
result = method.invoke(carService);
}
return result;
}
}
public class CarProxyDoTest {
public static void main(String[] args) {
CarServiceImpl carService = new CarServiceImpl();
CarInterface instance = new CarDoProxy().getInstance(carService);
instance.run();
instance.stop();
}
}
适配器模式
适配器模式主要是为了,对我们类和方法,在尽量少修改的前提下,进行亡羊补牢对方法进行修改
public class Phone { public void connect(TypeC typeC){ typeC.transmit(); } }
public class TypeC { public void transmit(){ System.out.println("Type-C 传输数据中..."); } }
public class TypeCAdapter extends TypeC { public final USBA usba; public TypeCAdapter(USBA usba) { this.usba = usba; } @Override public void transmit() { usba.transmit(); } }
public class USBA { public void transmit(){ System.out.println("USB-A 传输数据中..."); } }
public class TestDemo { public static void main(String[] args) { USBA usba = new USBA(); Phone phone = new Phone(); phone.connect(new TypeCAdapter(usba)); }标题一 }
这里的TypeC将转化为USBA来充电
装饰着模式
装饰着模式主要是动态的给对象增加一些额外的职责,生成的子类更加灵活,装饰着模式也被成为包装器
public interface IBeauty { int getBeautyValue(); }
public class Me implements IBeauty{ @Override public int getBeautyValue() { return 100; } }
public class RingDecorator implements IBeauty{ private final IBeauty me; public RingDecorator(IBeauty me) { this.me = me; } @Override public int getBeautyValue() { return me.getBeautyValue() + 20; } }
public class Client { public static void main(String[] args) { IBeauty me = new Me(); System.out.println("我的颜值:" + me.getBeautyValue()); IBeauty meWithRight = new RingDecorator(me); System.out.println("我带上戒指后的颜值:" + meWithRight.getBeautyValue()); } }
在JDK中,IO流就是用了大量的装饰着模式