1. Visão geral
No geral, os padrões de design são divididos em três categorias:
(1) Modo criativo , um total de cinco tipos: modo de método de fábrica, modo de fábrica abstrato, modo singleton, modo construtor e modo de protótipo.
(2) Modos estruturais , um total de sete tipos: modo adaptador, modo decorador, modo proxy, modo de aparência, modo de ponte, modo de combinação e modo de aproveitamento.
(3) Modo comportamental , um total de onze: modo de política, modo de método de modelo, modo de observador, sub-modo iterativo, modo de cadeia de responsabilidade, modo de comando, modo de memorando, modo de status, modo de visitante, modo intermediário e modo de intérprete.
2. Seis princípios de modelo de design
1. Princípio de fechamento aberto
O princípio de abertura e fechamento deve ser aberto a extensões e perto de modificações. Quando o programa precisa ser expandido, você não pode modificar o código original para obter um efeito de plugue a quente.
2. Princípio de substituição de Liskov
Sua descrição oficial é relativamente abstrata e pode ser usada para o Baidu. De fato, pode ser entendido da seguinte forma: (1) A capacidade de uma subclasse deve ser maior ou igual à classe pai, ou seja, os métodos que a classe pai pode usar e a subclasse pode usar. (2) O mesmo vale para o valor de retorno. Suponha que um método de classe pai retorne uma lista e uma subclasse retorna uma lista de Arraylist, que obviamente pode ser feita. Se o método da classe pai retornar um Arraylist e a classe criança devolver uma lista, não faz sentido. Aqui, a capacidade das subclasses de retornar valores é menor que a das classes dos pais. (3) Há também casos em que exceções são lançadas. Qualquer método de subclasse pode declarar uma subclasse que lança o método da classe pai para declarar uma exceção.
Não pode declarar que a exceção que a classe pai não declarou é lançada.
3. Princípio de inversão de dependência
Essa é a base do princípio de abertura e fechamento, e o conteúdo específico: programação orientada para interface, confiando na abstração em vez de concreto.
4. Princípio da segregação da interface
Esse princípio significa: o uso de várias interfaces isoladas é melhor do que usar uma única interface. Também significa reduzir o grau de acoplamento entre as classes. A partir daqui, podemos ver que o padrão de design é na verdade a idéia de design de um software, começando a partir de uma grande arquitetura de software, para a conveniência da atualização e manutenção. Portanto, o artigo acima apareceu muitas vezes: reduzir a dependência e reduzir o acoplamento.
5. Princípio Deméter
Por que o princípio do menor conhecimento? Ou seja, uma entidade deve interagir com outras entidades o mínimo possível, para que os módulos funcionais do sistema sejam relativamente independentes.
6. Princípio de reutilização composta
O princípio é tentar usar métodos de síntese/agregação em vez de herança.
3. Modo de criação
Existem cinco tipos de modos de criação: modo de método de fábrica, modo de fábrica abstrato, modo singleton, modo construtor e modo de protótipo.
3.1. Modelo de método de fábrica
O modo de método de fábrica é dividido em três tipos: modo comum de fábrica, modo de método de fábrica múltiplo e modo de método de fábrica estática.
3.1.1. Modelo de fábrica comum
O modelo de fábrica comum é estabelecer uma classe de fábrica e criar instâncias de algumas classes que implementam a mesma interface.
pacote com.mode.create; interface pública myinterface {public void print ();} pacote com.mode.create; classe pública myClassone implementa myinterface {@Override public void print () {System.out.println ("myClassone"); }} pacote com.mode.create; public class MyClasstwo implementa MyInterface {@Override public void print () {System.out.println ("myClasstwo"); }} pacote com.mode.create; public class MyFactory {public MyInterface Produce (String Type) {if ("One" .equals (tipo)) {return new MyClassone (); } else if ("dois" .equals (type)) {return new myclasstwo (); } else {System.out.println ("nenhum tipo a ser encontrado"); retornar nulo; }}} pacote com.mode.create; classe pública FactoryTest {public static void main (string [] args) {MyFactory Factory = new MyFactory (); MyInterface myi = factory.produce ("um"); myi.print (); }}Eu acho que os resultados do FactoryTest devem ser óbvios.
Vamos entender essa frase novamente: o modelo de fábrica comum é estabelecer uma classe de fábrica e criar instâncias de algumas classes que implementam a mesma interface.
3.1.2. Modos de método de fábrica múltiplos
Vários modos de método de fábrica são uma melhoria no modo de método de fábrica comum. Vários modos de método de fábrica devem fornecer vários métodos de fábrica para criar objetos separadamente.
Vejamos o código diretamente. Modificamos o MyFactory e o FactoryTest da seguinte maneira:
pacote com.mode.create; public class MyFactory {public myInterface ProduOne () {return New MyClassone (); } public myInterface produtetwo () {return New MyClasstwo (); }} pacote com.mode.create; classe pública FactoryTest {public static void main (string [] args) {MyFactory Factory = new MyFactory (); MyInterface myi = factory.produceOne (); myi.print (); }}Os resultados da operação também são muito óbvios.
Vamos entender esta frase novamente: vários modos de método de fábrica são uma melhoria no modo de método de fábrica comum. Vários modos de método de fábrica devem fornecer vários métodos de fábrica para criar objetos separadamente.
3.1.3. Modo de método de fábrica estática
Modo de método de fábrica estática, defina os métodos nos modos de método de fábrica acima para estática e não há necessidade de criar uma instância, basta chamá -la diretamente.
Vejamos o código diretamente. Modificamos o MyFactory e o FactoryTest da seguinte maneira:
pacote com.mode.create; public class MyFactory {public static myInterface ProduOne () {return New MyClassone (); } public static myInterface produtetwo () {return New MyClasstwo (); }} pacote com.mode.create; classe pública FactoryTest {public static void main (string [] args) {myInterface myi = myFactory.produceOne (); myi.print (); }}Os resultados da operação ainda são muito óbvios.
Revise novamente: Modo de método de fábrica estática, defina os métodos nos modos de método de fábrica acima acima como estática e não há necessidade de criar uma instância, basta chamá -la diretamente.
3.2. Padrão de fábrica abstrato
Há um problema com o modelo de método de fábrica de que a criação de classe depende de classes de fábrica, ou seja, se você deseja expandir o programa, deve modificar a classe de fábrica, que viola o princípio de fechamento.
Para resolver esse problema, vamos dar uma olhada no padrão abstrato de fábrica: crie várias classes de fábrica, para que, uma vez necessárias novas funções, você pode adicionar diretamente novas classes de fábrica, sem modificar o código anterior.
Isso está em conformidade com o princípio de fechamento.
Vamos dar uma olhada no código abaixo:
MyInterface, MyClassone, MyClasstwo permanece inalterado.
As seguintes interfaces e classes são adicionadas:
pacote com.mode.create; Provedor de interface pública {public myInterface Produce (); } pacote com.mode.create; public class MyFactoryOne implementa o provedor {@Override public MyInterface Produce () {return New MyClassone (); }} pacote com.mode.create; public class MyFactoryTwo implementa o provedor {@Override public myInterface Produce () {retorna new MyClasstwo (); }}Modifique a classe de teste FactoryTest da seguinte maneira:
pacote com.mode.create; classe pública FactoryTest {public static void main (string [] args) {provedor provedor = new myFactoryOne (); MyInterface myi = provider.produce (); myi.print (); }}Os resultados da operação ainda são óbvios.
Revisão novamente: O padrão de fábrica abstrato é criar várias classes de fábrica, para que, uma vez que novas funções sejam necessárias, você possa adicionar diretamente novas classes de fábrica, sem modificar o código anterior.
3.3. Modo singleton
Padrão Singleton, sem necessidade de muita explicação.
Basta olhar para o código:
teste de pacote; classe pública myObject {private estático myObject myObject; private myObject () {} public static myObject getInstance () {if (myObject! = null) {} else {myObject = new MyObject (); } retornar myObject; }}No entanto, isso causará problemas com vários threading. Para uma explicação detalhada, você pode ver o capítulo 6 no livro "Core Technology of Java multi-threading Programming".
3.4. Modo construtor
Padrão do construtor: é separar a construção de um objeto complexo de sua representação, para que o mesmo processo de construção possa criar representações diferentes.
Parece muito abstrato literalmente, mas na verdade também é muito abstrato! ! ! !
O modo Builder geralmente inclui os seguintes caracteres:
(1) Builder: Dê uma interface abstrata para padronizar a construção de vários componentes do objeto do produto. Esta interface especifica quais partes de objetos complexos são criados e não envolve a criação de componentes de objetos específicos.
(2) ConcreteBuilder: implementa a interface do construtor e define a criação de várias partes de objetos complexos para diferentes lógicas de negócios. Após a conclusão do processo de construção, é fornecido um exemplo do produto.
(3) Diretor: chama construtores específicos para criar várias partes de objetos complexos. O instrutor não envolve informações específicas do produto, mas é responsável apenas por garantir que todas as partes do objeto sejam criadas intactas ou em uma determinada ordem.
(4) Produto: o objeto complexo a ser criado.
É comum construir vilões no desenvolvimento de jogos, e o requisito é: os vilões devem incluir cabeça, corpo e pés.
Vamos dar uma olhada no seguinte código:
Produto (objeto complexo a ser criado.):
pacote com.mode.create; public class Pessoa {private String Head; corpo de cordas privadas; pé de corda privada; public string gethead () {return Head; } public void sethead (string head) {this.head = head; } public string getBody () {retornar corpo; } public void setBody (String body) {this.body = body; } public String getFoot () {return Foot; } public void setfoot (string pé) {this.foot = fé; }} Builder (fornece uma interface abstrata para padronizar a construção de vários componentes de um objeto de produto. Esta interface especifica quais partes de um objeto complexo são criadas para serem implementadas e não envolve a criação de componentes de objeto específicos.):
pacote com.mode.create; interface pública Personbuilder {void acwitchead (); Void Buildbody (); void BuildFoot (); Pessoa BuildPerson ();} ConcreteBuilder (implementa a interface do construtor, que incorpora a criação de várias partes de objetos complexos para diferentes lógicas de negócios. Após a conclusão do processo de construção, forneça um exemplo do produto.):
pacote com.mode.create; classe pública manbuilder implementa o personbuilder {pessoa pessoa; public manbuilder () {pessoa = new Person (); } public void BuildBody () {Person.Setbody ("Construa o corpo do homem"); } public void BuildFoot () {Person.SetFoot ("Construa os pés do homem"); } public void BuildHead () {Person.sethead ("Construa a cabeça do homem"); } public Person BuildPerson () {Return Person; }} Diretor (ligue para o construtor específico para criar várias partes de objetos complexos. O instrutor não envolve informações específicas do produto. É responsável apenas por garantir que as partes do objeto sejam criadas intactas ou em uma determinada ordem.):
pacote com.mode.create; classe pública Persondirector {public Person ConstructPerson (PersonBuilder PB) {pb.buildhead (); pb.buildbody (); pb.buildfoot (); return pb.buildperson (); }} Classe de teste:
pacote com.mode.create; public class Test {public static void main (string [] args) {persondirector Pd = new Persondirector (); Pessoa pessoa = pd.ConstructPerson (New Manbuilder ()); System.out.println (Person.getBody ()); System.out.println (PERSON.GETFOOT ()); System.out.println (PERSON.GETHEAD ()); }}Resultados em execução:
Revisão: padrão do construtor: é separar a construção de um objeto complexo de sua representação, para que o mesmo processo de construção possa criar representações diferentes.
3.5. Modo de protótipo
A idéia desse padrão é usar um objeto como um protótipo, copiar e cloná -lo e produzir um novo objeto semelhante ao objeto original.
Falando em copiar objetos, falarei sobre isso em combinação com cópia superficial e cópia profunda de objetos. Primeiro de tudo, você precisa entender o conceito de cópia profunda e superficial de objetos:
Cópia rasa: Após copiar um objeto, as variáveis do tipo de dados básicas serão recriadas, enquanto o tipo de referência aponta para o objeto original.
Cópia profunda: depois de copiar um objeto, o tipo de dados básico e o tipo de referência são recriados. Simplificando, a cópia profunda é completamente copiada, enquanto a cópia superficial não é completa.
Escreva um exemplo de profundidade de cópia:
pacote com.mode.create; importar java.io.byteArrayInputStream; importar java.io.bytearrayoutputStream; importar java.io.ioException; importar java.io.objectinputStream; importar java.io.objectTream; importar java.io.serializable; classe pública protótipo implementa clonável, serializável {private estático final serialversionuid = 1L; base privada int; Inteiro privado OBJ; /* cópia rasa*/ public objeto clone () lança clonenotsupportedException {// Como a interface clonável é uma interface vazia, você pode definir o nome do método da classe de implementação em vontade // como clone (cloneb), porque o foco aqui é o clone de se sentença. Prototype proto = (prototype) super.clone (); retornar proto; } /* cópia profunda* / public Object DeepClone () lança ioexception, classNotFoundException { /* Escreva o fluxo binário no objeto atual* / bytearrayOutputStream bos = new ByteArrayOutputStream (); ObjectOutputStream ooS = new ObjectOutputStream (BOS); OOS.WriteObject (this); /* Leia o novo objeto gerado pelo fluxo binário*/ byteArrayInputStream bis = new ByteArrayInputStream (bos.tobytearray ()); ObjectInputStream ois = new ObjectInputStream (bis); retornar oIS.readObject (); } public int getBase () {return base; } public void setBase (int base) {this.base = base; } public integer getObj () {return obj; } public void setObj (Inteiro obj) {this.obj = obj; }} Classe de teste:
pacote com.mode.create; importar java.io.ioException; public class Test {public static void main (string [] args) lança clonenotsupportedException, classNotFoundException, ioexception {prototype prototype = new prototype (); prototype.setBase (1); prototype.setObj (novo número inteiro (2)); /* cópia rasa*/ prototype prototype1 = (prototype) prototype.clone (); /* Cópia profunda*/ prototype prototype2 = (prototype) prototype.deepClone (); System.out.println (prototype1.getObj () == prototype1.getObj ()); System.out.println (prototype1.getObj () == prototype2.getObj ()); }}Resultados em execução:
O exposto acima é tudo sobre este artigo, espero que seja útil para o aprendizado de todos.