자바 상용 디자인 모델 학습 총화
창설 형: 단일 모드, 공장 방법 모드 등
구조 형: 정적 에이전트 모드, 동적 에이전트 모드, 장식 자 모드, 어댑터 모드, 브리지 모드
행위 형: 관찰자 모드, 명령 모드, 책임 체인 모드, 상태 모드, 방문 자 모드
1. 단일 모드
응용 장면: 말 그대로 처음부터 끝까지 같은 대상 을 조작 할 때 단일 모델 을 사용 해 야 한다.
/**
* ( )
*/
public class SingletonPatternLazy {
private SingletonPatternLazy() {}
public static SingletonPatternLazy getInstance () {
return SingletonPatternInstance.singletonPatternLazy;
}
private static class SingletonPatternInstance {
final static SingletonPatternLazy singletonPatternLazy = new SingletonPatternLazy();
}
public static void main(String[] args) {
SingletonPatternLazy instance1 = SingletonPatternLazy.getInstance();
SingletonPatternLazy instance2 = SingletonPatternLazy.getInstance();
System.out.println(instance1 == instance2);
}
}
/**
* ( )
*/
public class SingletonPattern {
private SingletonPattern() {}
private final static SingletonPattern singletonPattern = new SingletonPattern();
public static SingletonPattern getInstance() {
return singletonPattern;
}
public static void main(String[] args) {
SingletonPattern instance1 = SingletonPattern.getInstance();
SingletonPattern instance2 = SingletonPattern.getInstance();
System.out.println(instance1 == instance2);
}
}
단일 모드 최적화 업그레이드 버 전 (추천)
/**
* ( )
*/
public class SingletonPatternLazy {
private static SingletonPatternLazy instance = null;
private SingletonPatternLazy() {
}
public static SingletonPatternLazy getInstance() {
if (instance == null) {
newInstance();
}
return instance;
}
private synchronized static void newInstance() {
if (instance == null) {
instance = new SingletonPatternLazy();
}
}
public static void main(String[] args) {
for(int i = 0; i < 100; i ++) {
new Thread(() -> System.out.println(SingletonPatternLazy.getInstance())).start();
}
}
}
2. 공장 방법 모델
응용 필드:
우 리 는 같은 규범 에서 서로 다른 실현 대상 을 얻 고 이런 대상 을 얻 을 때 비교적 번 거 로 운 상황 에서 공장 모델 을 사용 하 는 것 을 고려 할 수 있다.
확장 규범 이 실 현 될 때 공장 을 확장 해 야 한다. 확장 에 편리 하고 개폐 원칙 에 적응 하기 위해 공장 방법 모델 이 생 겼 다. 즉, 한 공장 은 규범 아래 의 실현 대상 만 만 만 들 었 다.
서로 다른 대상 이 서로 다른 공장 을 만 들 면 서로 다른 공장 들 은 하나의 템 플 릿 을 추상 화하 거나 인 터 페 이 스 를 미리 정의 할 수 있다.
/*
* source
*/
//Person
public interface Person {
void work();
}
//Person ,Programmer
public class Programmer implements Person {
@Override
public void work() {
System.out.println(" work");
}
}
/*
*
*/
//
public interface PersonFactory {
Person getInstance();
}
// ProgrammerFactory
public class ProgrammerFactory implements PersonFactory {
private Programmer programmer;
@Override
public Person getInstance() {
if(programmer == null) {
newInstance();
}
return programmer;
}
private synchronized void newInstance() {
if(programmer == null) {
programmer = new Programmer();
}
}
}
/*
*
*/
public class PersonFactoryBuilder {
public static PersonFactory build(Class extends PersonFactory> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
PersonFactory personFactory = PersonFactoryBuilder.build(ProgrammerFactory.class);
for(int i = 0; i < 100; i ++) {
new Thread(() -> System.out.println(personFactory.getInstance())).start();
}
}
}
3. 정적 에이전트 모드
응용 장면: 많이 사용 하지 않 습 니 다. 보통 동적 대 리 를 사용 합 니 다.
//
public interface IPerson {
void doSome();
}
//
public class Person implements IPerson{
public void doSome(){
System.out.println(" ...");
}
}
//
public class PersonProxy implements IPerson{
private IPerson person;
//
public PersonProxy(IPerson person){
this.person = person;
}
public void doSome(){
before();
person.doSome();
after();
}
public void before(){
System.out.println("before...");
}
public void after(){
System.out.println("after...");
}
}
/*
*
*/
public static void testProxy(){
IPerson proxy = new PersonProxy(new Person());
proxy.doSome();
}
4. 동적 에이전트 모드
응용 장면: spring 의 op 바 텀 은 동적 대 리 를 바탕 으로 하 는 것 입 니 다. 우 리 는 가로로 프로그램 을 확장 해 야 합 니 다. 즉, 임의의 대상 을 확장 하 는 방법 이 필요 할 때 동적 대 리 를 사용 할 수 있 습 니 다.
jdk 동적 에이전트
//
public interface ISource {
void doSome(String inputSome);
}
//
public class SourceImpl implements ISource{
public void doSome(String inputSome){
System.out.println(" , :" + inputSome);
}
}
//
public class BeforeAfterInvocationHandler implements InvocationHandler {
private Object source;
public BeforeAfterInvocationHandler(Object source){
this.source = source;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
before();
method.invoke(source, args);
after();
return null;
}
public void before(){
System.out.println("------ before-------");
}
public void after(){
System.out.println("------ after-------");
}
/**
* t
* @param t
* @return
*/
@SuppressWarnings("all")
public static T getProxy(T t){
BeforeAfterInvocationHandler invocationHandler = new BeforeAfterInvocationHandler(t);
Class[] interfaces = t.getClass().getInterfaces();
T tProxy = (T) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(), interfaces, invocationHandler);
return tProxy;
}
}
//
public static void testDynamicProxy(){
ISource source = new SourceImpl();
BeforeAfterInvocationHandler.getProxy(source).doSome(" ");
}
cglib 동적 에이전트
cglib 에 의존:
cglib cglib 3.3.0
//
public class Programmer {
public String getUsername() {
return "lucy";
}
public void doSome() {
System.out.println(" doSome()");
}
}
//
public class CGlibProxyHandler implements MethodInterceptor {
public Object createProxy(Object source){
Enhancer enhancer = new Enhancer();
enhancer.setCallback(this);
enhancer.setSuperclass(source.getClass());
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before(obj, args);
Object object = proxy.invokeSuper(obj, args);
after(object);
return object;
}
//
private void before(Object obj, Object[] args) {
System.out.println("before:" + obj.getClass().getSuperclass().getName());
}
//
private void after(Object object) {
System.out.println("after:" + JSONObject.toJSONString(object));
}
@SuppressWarnings("unchecked")
public static T getProxy(T t){
CGlibProxyHandler handler = new CGlibProxyHandler();
return (T) handler.createProxy(t);
}
}
//
public static void main(String[] args) {
Programmer proxy = CGlibProxyHandler.getProxy(new Programmer());
String name = proxy.getUsername();
System.out.println(name);
proxy.doSome();
}
5. 장식 자 모드
응용 장면: 우리 가 동적 인 가로 확장 프로그램 이 필요 할 때, 즉 특정한 대상 을 동적 으로 확장 하 는 방법 으로 장식 자 모드 를 사용 할 수 있 습 니 다.
동적 에이전트 와 의 차이 점 주의:
동적 대 리 는 임의의 대상 을 확장 하 는 방법 이지 만 확장 내용 은 고정 적 으로 변 하지 않 습 니 다.
장식 자 모드 는 특정한 대상 의 방법 을 확장 하고 확장 하 는 내용 은 동적 으로 변화 할 수 있다.
//
public interface IPerson {
void doSome();
}
//
public class PersonImpl implements IPerson {
public void doSome() {
System.out.println(" ....");
}
}
//
public abstract class PersonDecorator implements IPerson {
private IPerson person;
public PersonDecorator(IPerson person){
this.person = person;
}
// person dosome()
public void doSome() {
person.doSome();
}
}
// Student
public class Student extends PersonDecorator {
// person
public Student(IPerson person){
//
super(person);
}
public void doSome(){
/*
* , doSome()
* , person dosome()
*/
super.doSome();
System.out.println(" ...");
}
}
// Worker
public class Worker extends PersonDecorator {
public Worker(IPerson person){
super(person);
}
public void doSome(){
super.doSome();
System.out.println(" ...");
}
}
//
public static void testDecorator(){
// person
PersonImpl person = new PersonImpl();
System.out.println("--------------person: --------------");
// person
person.doSome();
// worker person
Worker worker = new Worker(person);
System.out.println("--------------worker: --------------");
// worker person
worker.doSome();
// worker
Student student = new Student(worker);
System.out.println("--------------student: --------------");
// worker
student.doSome();
}
6. 어댑터 모드
응용 장면: 예 를 들 어 응용 에 A 류 가 하나 있 고 규범 이 하나 있 으 며 규범 화 된 특정한 방법 이나 여러 가지 방법 이 A 류 와 똑 같은 실현 을 가지 기 때문에 이런 방법 을 따로 실현 할 필요 가 없다. 추상 적 인 어댑터 류 를 추가 하고 유형 A 를 직접 계승 한 다음 에 새로운 추상 적 인 규범 을 정의 할 수 있다.
//
public class Animal {
public void eat() {
System.out.println("eat()*************************");
}
}
// Animal
public interface IPerson {
public void doWork();
}
//
public class AnimalAdpter extends Animal implements IPerson {
@Override
public void doWork() {
before();
super.eat();
after();
}
private void before() {
System.out.println("AnimalAdpter.before()*************************");
}
private void after() {
System.out.println("AnimalAdpter.after()*************************");
}
public static void main(String[] args) {
IPerson person = new AnimalAdpter();
person.doWork();
}
}
7. 브리지 모드
응용 장면: 우리 가 조작 규범 이 필요 하지만 고정 적 으로 실현 할 수 없 을 때 한 조 의 규범 을 제공 하여 고객 측 이 실현 하도록 할 수 있다. 우리 가 조작 할 때 고객 측의 실현 대상 만 주입 해 야 한다. 이런 모델 은 바로 브리지 모델 이다. 예 를 들 어 jdbc 는 구동 규범 을 정 의 했 고 각 데이터 베이스 업 체 는 서로 다른 구동 실현 을 제공 했다.
// IBridgeAble
public interface IBridgeAble {
public void doSome(String arg0, String arg1);
}
// BridgeAble
public class BridgeAble implements IBridgeAble {
private IBridgeAble bridgeAble;
public BridgeAble(IBridgeAble bridgeAble){
this.bridgeAble = bridgeAble;
}
public void doSome(String arg0, String arg1) {
bridgeAble.doSome(arg0, arg1);
}
}
//A BrideAbleImplA
public class BrideAbleImplA implements IBridgeAble{
public void doSome(String arg0, String arg1) {
System.out.println("BrideAbleImplA.arg0: " + arg0 + " BrideAbleImplA.arg1: " + arg1);
}
}
//B BrideAbleImplB
public class BrideAbleImplB implements IBridgeAble{
public void doSome(String arg0, String arg1) {
System.out.println("BrideAbleImplB.arg0: " + arg0 + " BrideAbleImplB.arg1: " + arg1);
}
}
//
public static void testBridge(){
BridgeAble bridge = new BridgeAble(new BrideAbleImplA());
bridge.doSome("A", "A1");
}
8. 관찰자 모드
응용 장면: 관찰자 모델 은 이해 하기 어렵 지만 매우 중요 하 다. 예 를 들 어 모니터 는 관찰자 모델 로 실현 해 야 한다.
//
public interface IObserver {
void operate();
}
// ObserverOne, , ,
public class ObserverOne implements IObserver {
@Override
public void operate() {
System.out.println(" 1 ");
}
}
// ObserverTwo
public class ObserverTwo implements IObserver {
@Override
public void operate() {
System.out.println(" 2 ");
}
}
// BeObserver
public abstract class BeObserver {
private Set observers;
public BeObserver(Set observers) {
this.observers = observers;
}
public abstract void doSome();
protected void notifyObserver() {
if(observers != null) {
observers.forEach(observer -> observer.operate());
}
}
}
// DefaultBeObserver
public class DefaultBeObserver extends BeObserver {
public DefaultBeObserver(Set observers) {
super(observers);
}
@Override
public void doSome() {
super.notifyObserver();
System.out.println("doSome()***********");
}
}
//
public static void testObserver(){
HashSet observers = new HashSet();
observers.add(new ObserverOne());
observers.add(new ObserverTwo());
new DefaultBeObserver(observers).doSome();
}
9. 모니터
//
public class Event {
public void print() {
System.out.println(" :" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date()));
}
}
//
public interface Listener {
void onEvent(Event e);
}
//
public class ListenerImpl implements Listener{
@Override
public void onEvent(Event e) {
e.print();
}
}
//
public class EventResource {
private List listenerList = new ArrayList<>();
private Event e = new Event();
public void register(Listener listener) {
this.listenerList.add(listener);
}
public void operte() {
System.out.println("EventResource.operte***************");
this.listenerList.forEach(listener -> listener.onEvent(e));
}
public static void main(String[] args) {
EventResource eventResource = new EventResource();
eventResource.register(new ListenerImpl());
eventResource.operte();
}
}
10. 명령 모드
응용 장면: 응용 이 그리 광범 위 하지 않 습 니 다. 예 를 들 어 activiti 는 데이터 베이스 에 대한 각종 조작 에 대해 명령 모드 를 사 용 했 습 니 다. activiti 는 데이터 베이스 에 대한 조작 을 모두 서로 다른 명령 에 밀봉 하고 호출 자 는 명령 을 내 리 는 사람 입 니 다. 데이터 베 이 스 를 조작 하 는 API 즉 집행 자 이 며 서로 의존 하 는 인 터 페 이 스 는 디 결합 입 니 다.
여기 에는 세 개의 대상, 명령 하달 자 (명령 대상 소지), 명령 (최소한 하나의 명령 집행자 대상 과 명령 내용 소지), 명령 집행자 (명령 집행) 에 주의해 야 한다.
//
public interface ILeader {
//
void command();
}
//
public class LeaderImplOne implements ILeader{
//
private ICommand command;
//
public LeaderImplOne(ICommand command){
this.command = command;
}
//
public void command() {
command.transferCommand();
}
}
// ...N
//
public interface ICommand {
//
void transferCommand();
}
// 1
public class CommandImplOne implements ICommand{
//
private IExecutor[] executors;
//
private IExecutor executor;
//
private String content;
// , ,
public CommandImplOne (IExecutor[] executors,String content){
this.executors = executors;
this.content = content;
}
// , ,
public CommandImplOne (IExecutor executor,String content){
this.executor = executor;
this.content = content;
}
//
public void transferCommand() {
if(executors != null && executors.length > 0){
for(int i = 0; i < executors.length; i++){
executors[i].execute(content);
}
}
if(executor != null){
executor.execute(content);
}
}
}
// 2
public class CommandImplTwo implements ICommand{
//
private IExecutor[] executors;
//
private IExecutor executor;
//
private Map content;
// , ,
public CommandImplTwo (IExecutor[] executors,Map content){
this.executors = executors;
this.content = content;
}
// , ,
public CommandImplTwo (IExecutor executor,Map content){
this.executor = executor;
this.content = content;
}
//
public void transferCommand() {
if(executors != null && executors.length > 0){
for(int i = 0; i < executors.length; i++){
executors[i].execute(content);
}
}
if(executor != null){
executor.execute(content);
}
}
}
// ...N
//
public interface IExecutor {
//
void execute(String content);
//
void execute(Map content);
}
// 1
public class ExecutorImplOne implements IExecutor {
public void execute(String content) {
//
System.out.println(" 1 , content:" + content);
}
public void execute(Map content) {
//
System.out.println(" 1 , content.size:" + content.size());
}
}
// 2
public class ExecutorImpTwo implements IExecutor {
public void execute(String content) {
//
System.out.println(" 2 , content:" + content);
}
public void execute(Map content) {
//
System.out.println(" 2 , content.size:" + content.size());
}
}
// ...N
//
public static void testCommand(){
//
IExecutor[] executors = {new ExecutorImplOne(),new ExecutorImpTwo()};
// , ,
CommandImplOne commandOne = new CommandImplOne(executors," 1");
// ,
new LeaderImplOne(commandOne).command();
}
11. 책임 체인 모드
응용 장면: 책임 체인 의 응용 은 상당히 광범 위 하 다. 예 를 들 어 springmvc 의 프로세서 체인 은 이 디자인 모델 을 사용 했다. 그 원 리 는 프론트 데스크 톱 에서 요청 을 보 내 면 프로세서 체인 의 각종 차단기 에 의 해 차단 되 고 각자 의 처 리 를 하 는 것 이다.한 마디 로 하면 만약 에 한 대상 이 다른 여러 대상 에 의 해 서로 다른 처 리 를 해 야 하고 이 과정 이 선형, 즉 동기 화 되 어야 한다 면 우 리 는 책임 체인 모델 을 사용 하 는 것 을 고려 할 수 있다.이렇게 하 는 장점 은 피 처리 대상 과 각 처리 대상 이 결합 을 풀 고 자 유 롭 게 조립 하 는 것 이다.
//
public abstract class Handler {
//
protected Handler nextHandler;
//
protected Handler lastHandler;
//
protected String handlerName;
//
public Handler (String handlerName){
this.handlerName = handlerName;
}
// ,
public void setNextHandler(Handler nextHandler){
this.nextHandler = nextHandler;
nextHandler.lastHandler = this;
}
// , Request
public abstract void handle(Request request);
}
//
public class Request {
// map
private Map attributes;
// , new attributes
public Request(){
attributes = new HashMap<>();
}
// attributes
public Request(Map attributes){
this.attributes = attributes;
}
//attributes set、get
public Map getAttributes() {
return attributes;
}
public void setAttributes(Map attributes) {
this.attributes = attributes;
}
// attributes
public void setAttribute(String key,Object value){
attributes.put(key, value);
}
// key attributes
public Object getAttribute(String key){
return attributes.get(key);
}
}
// HandlerImplA
public class HandlerImplA extends Handler {
public HandlerImplA(String handlerName) {
super(handlerName);
}
@Override
public void handle(Request request) {
System.out.println("HandlerImplA request :" + request.getAttributes().size());
request.setAttribute(this.handlerName + ".attr", this.handlerName + ".val");
nextHandler.handle(request);
}
}
// HandlerImplB
public class HandlerImplB extends Handler {
public HandlerImplB(String handlerName) {
super(handlerName);
}
@Override
public void handle(Request request) {
System.out.println("HandlerImplB :" + lastHandler.handlerName);
nextHandler.handle(request);
}
}
// ActualHandler
public class ActualHandler extends Handler {
public ActualHandler(String handlerName) {
super(handlerName);
}
@Override
public void handle(Request request) {
System.out.println("ActualHandler request :");
Map attributes = request.getAttributes();
Set> entrySet = attributes.entrySet();
for (Entry entry : entrySet) {
System.out.println("request.attrName:" + entry.getKey() + " request.attrVal:" + entry.getValue());
}
}
}
//
public static void testResponsibility(){
//
Request request = new Request();
ActualHandler handler = new ActualHandler("handler");
HandlerImplB handlerB = new HandlerImplB("handlerB");
handlerB.setNextHandler(handler);
HandlerImplA handlerA = new HandlerImplA("handlerA");
handlerA.setNextHandler(handlerB);
// A
handlerA.handle(request);
}
콘 솔 인쇄 는 다음 과 같 습 니 다.
HandlerImplA 현재 request 의 속성 을 인쇄 합 니 다: 0 HandlerImplB 이전 처리 이름 을 인쇄 합 니 다: handlerA ActualHandler 인쇄 request 의 모든 매개 변 수 는 다음 과 같 습 니 다: request. attrName: handlerA. attr request. attrVal: handlerA. val
12. 상태 모드
응용 장면: 논리 적 으로 3 층 이 넘 는 if - else 코드 는 위 문 이나 상태 모드 를 사용 하여 실현 할 수 있 습 니 다.이 말 은 아 리 의 자바 개발 매 뉴 얼 의 규범 으로 뚜렷 하 다. 상태 모델 의 디자인 은 if - else 를 교체 하기 위 한 것 이다.그렇다면 왜 상태 모드 로 if - else 를 교체 해 야 합 니까?이것 이 바로 상태 모드 를 사용 하 는 이유 입 니 다. 인터넷 에서 대부분 사람들 이 부화뇌동 하 는 것 은 유지 와 확장 을 편리 하 게 하기 위해 서 라 고 설명 하지만 상태 모드 를 사용 하면 어떻게 원래 코드 를 수정 하지 않 고 확장 할 수 있 는 지 생각 하지 않 았 습 니 다. 하지만 배 워 보 세 요. 유지 하기 쉽 기 때 문 입 니 다.
//
public class ThingObject {
//
private StateTemplate state;
// null
public ThingObject() {
this.state = null;
}
//
public StateTemplate getState() {
return state;
}
// ,
public boolean setState(StateTemplate state) {
this.state = state;
return state.doAction();
}
//
public static void doAction(){
//
System.out.println(" ");
}
}
//
public abstract class StateTemplate {
//
protected int states;
//
public StateTemplate(int states){
this.states = states;
}
//
public abstract boolean doAction();
}
// states
public enum StatesEnum {
STATE1(1),STATE2(2),STATE3(3),STATE4(4),STATE5(5),STATE6(6),STATE7(7),STATE8(8);
public Integer value;
private StatesEnum(Integer value){
this.value = value;
}
}
// 1
public class StateOne extends StateTemplate {
//
public StateOne(int states) {
super(states);
}
@Override
public boolean doAction() {
// 1 ,
if(super.states == StatesEnum.STATE1.value){
System.out.println(" 111 ");
return true;
}
return false;
}
}
// 2
public class StateTwo extends StateTemplate {
public StateTwo(int states) {
super(states);
}
@Override
public boolean doAction() {
if(super.states == StatesEnum.STATE2.value){
// 2
System.out.println(" 222 ");
return true;
}
return false;
}
}
// 3
public class StateThree extends StateTemplate {
public StateThree(int states) {
super(states);
}
@Override
public boolean doAction() {
if(super.states == StatesEnum.STATE3.value){
// 2
System.out.println(" 333 ");
return true;
}
return false;
}
}
// N...
//
public static void testState(int states){
ThingObject t = new ThingObject();
if(t.setState(new StateOne(states))) return;
if(t.setState(new StateTwo(states))) return;
if(t.setState(new StateThree(states))) return;
//
ThingObject.doAction();
}
상기 테스트 코드 의 if return 은 지 울 수 있 습 니 다. if - else 의 효 과 를 완전히 모 의 하기 위해 서 만 추 가 됩 니 다. 만약 에 지금 조건 4 를 확장 해 야 한다 면 상태 템 플 릿 을 추가 하여 State Four 를 실현 한 다음 에 테스트 코드 의 마지막 줄 에 if (t. setState (new State Four (states) return 을 추가 합 니 다.즉, 클 라 이언 트 가 소스 코드 를 수정 해 야 하 는 것 이 분명 하고 개폐 원칙 을 진정 으로 실현 하지 못 했다.
13. 방문 자 모드
응용 장면: 소스 대상 에 대한 다양한 조작 을 추상 적 으로 하나의 규범 으로 만 든 다음 에 이 규범 을 실현 하 는 각 실현 유형 은 바로 방문 자 대상 이 고 방문 자 는 소스 대상 을 가지 기 때문에 소스 대상 의 데이터 구 조 를 조작 할 수 있다.이 럴 때 이 모델 을 사용 할 수 있다. 예 를 들 어 한 모듈 의 여러 장의 보고 서 를 개발 할 때 이 모델 을 사용 할 수 있다. 보고 서 를 추가 할 필요 가 있 으 면 방문 자 를 추가 하면 된다.
//
public class BeVisitor {
//
public void accept(IVisitor visitor) {
visitor.visite(this);
}
private Integer attr1;
private String attr2;
private boolean attr3;
public Integer getAttr1() {
return attr1;
}
public void setAttr1(Integer attr1) {
this.attr1 = attr1;
}
public String getAttr2() {
return attr2;
}
public void setAttr2(String attr2) {
this.attr2 = attr2;
}
public boolean isAttr3() {
return attr3;
}
public void setAttr3(boolean attr3) {
this.attr3 = attr3;
}
}
//
public interface IVisitor {
void visite(BeVisitor beVisitor);
}
// 1
public class VisitorOne implements IVisitor {
public void visite(BeVisitor beVisitor) {
System.out.println("------------VisitorOne print:------------");
System.out.println(beVisitor.getAttr1() + "---" + beVisitor.getAttr2());
}
}
// 2
public class VisitorTwo implements IVisitor {
public void visite(BeVisitor beVisitor) {
System.out.println("------------VisitorTwo print:------------");
if(beVisitor.isAttr3()){
System.out.println(beVisitor.getAttr1() + "---" + beVisitor.getAttr2());
}else{
System.out.println("beVisitor.isAttr3(): " + false);
}
}
}
//
public static void testVisitor(){
BeVisitor beVisitor = new BeVisitor();
beVisitor.setAttr1(20);
beVisitor.setAttr2(" ");
beVisitor.setAttr3(false);
// 1
beVisitor.accept(new VisitorOne());
// 2
beVisitor.accept(new VisitorTwo());
}
14. 템 플 릿 방법
응용 장면: 만약 에 규범 중의 방법 을 각각 실현 해 야 한다 면 이런 모델 을 사용 할 수 있다.
//
public interface IPhone {
public void call();
public void photograph();
public void music();
public void sendMsg();
}
//
public abstract class PhoneTemplate implements IPhone {
@Override
public void call() {
System.out.println("call()*********");
}
@Override
public void sendMsg() {
System.out.println("sendMsg()********");
}
}
// Vivo
public class Vivo extends PhoneTemplate {
@Override
public void photograph() {
System.out.println("vivo -> photograph()********");
}
@Override
public void music() {
System.out.println("vivo -> music()********");
}
}
// XiaoMi
public class XiaoMi extends PhoneTemplate {
@Override
public void photograph() {
System.out.println("XiaoMi -> photograph()********");
}
@Override
public void music() {
System.out.println("XiaoMi -> music()********");
}
}
//
public static void main(String[] args) {
XiaoMi xiaoMi = new XiaoMi();
xiaoMi.call();
xiaoMi.sendMsg();
xiaoMi.music();
}
15. 전략 모드
사용 장면 이 매우 광범 위 하고 한 행위 가 서로 다른 표현 형식 을 가 질 때 전략 모델 을 사용 할 수 있다.
전략 모델 과 브리지 모델 은 코드 차원 에서 본질 적 인 차이 가 없고 디자인 의 출발점 만 다르다.
예 를 들 어 네 가지 연산 법칙 은 하나의 연산 행위 (전략) 를 정의 하고 가감 곱 하기 네 가지 연산 형식 (전략 실현) 이 있 으 며 전략 소지 (전략 사용자) 가 있다.
//
public interface StrategyCalculate {
public double calculate(double a, double b);
}
//
public class DefaultStrategyCalculate implements StrategyCalculate {
@Override
public double calculate(double a, double b) {
return a + b;
}
}
//
public class SubtractionStrategyCalculate implements StrategyCalculate {
@Override
public double calculate(double a, double b) {
return a - b;
}
}
//
public class StrategyCalculateHolder {
private StrategyCalculate strategyCalculate;
public StrategyCalculateHolder(StrategyCalculate strategyCalculate) {
this.strategyCalculate = strategyCalculate;
}
public double calculate(double a, double b) {
return this.strategyCalculate.calculate(a, b);
}
public static void main(String[] args) {
System.out.println(new StrategyCalculateHolder(new DefaultStrategyCalculate()).calculate(20, 10));
System.out.println(new StrategyCalculateHolder(new SubtractionStrategyCalculate()).calculate(20, 10));
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.