Padrões de design por tutoriais - O poder da OOP (parte 1)
Jornada dos Padrões de Design – O Poder do OOP 1
Padrões de design por tutoriais - O poder da OOP (parte 1)
Pré-requisitos — Esta série de blogs requer um nível intermediário de conhecimento em programação orientada a objetos. Você deve ter conhecimentos básicos sobre classe, objeto, construtor, herança, valor e tipo de referência. Um intermediário adquirirá conhecimento e os especialistas aprimorarão seu conhecimento lendo esta série do início ao fim. Pré-requisitos – Esta série de blogs requer conhecimento intermediário em programação orientada a objetos. Você deve ter um conhecimento básico de classes, objetos, construtores, herança, valor e tipos de referência. Um intermediário adquirirá conhecimento e um especialista aprimorará seu conhecimento lendo esta série do início ao fim.
Padrões de projeto são usados para representar as melhores práticas adotadas pela experiente comunidade de desenvolvedores de software orientado a objetos. Os padrões de projeto são usados para representar as melhores práticas adotadas por uma comunidade de desenvolvedores experientes de software orientado a objetos.
O padrão de design do construtor nos ajuda a construir um objeto de uma forma mais simples e legível. O padrão de design do construtor segue duas regras simples mencionadas abaixo. O padrão de design do construtor nos ajuda a construir objetos de uma forma mais simples e legível. O padrão de design do construtor segue duas regras simples, descritas abaixo.
-
Separe a representação da classe original e seus métodos de construção. Separe a representação da classe original e seu construtor.
-
retorna a instância da classe na etapa final Retorne uma instância da classe na etapa final
O melhor exemplo de padrão de design de construtor é SwiftUI, sim, você leu certo. SwiftUI usa padrão de design de construtor para a maioria de suas classes, por exemplo. Texto, Imagem O melhor exemplo de padrão de design de construtor é SwiftUI, sim, você leu certo. A maioria das classes no SwiftUI usa o padrão de design do construtor, como texto, imagens, etc.
Problema: Pergunta:
Pense na classe, digamos Person, com dez ou mais propriedades, imaginando seu design de construtor quando você precisar criar uma instância da classe Person. Seu construtor receberá dez ou mais argumentos, será difícil gerenciar esses muitos argumentos como uma única função ou construtor e, eventualmente, você perderá a legibilidade do código. confira o exemplo abaixo. Pense nesta classe, digamos Person tendo dez ou mais propriedades, quando você precisar criar uma instância da classe Person, imagine seu design de construtor. Seu construtor requer 10 ou mais parâmetros, que são difíceis de gerenciar como uma função ou construtor e, eventualmente, você perde a legibilidade do seu código. Confira o exemplo abaixo.
WithoutDesignPatternExample1.swift:
class Person {
//personal details
var name: String = ""
var gender: String = ""
var birthDate: String = ""
var birthPlace: String = ""
var height: String = ""
var weight: String = ""
//contact details
var phone: String = ""
var email: String = ""
//address details
var streeAddress: String = ""
var zipCode: String = ""
var city: String = ""
//work details
var companyName: String = ""
var designation: String = ""
var annualIncome: String = ""
//constructor
init(name: String,
gender: String,
birthDate: String,
birthPlace: String,
height: String,
weight: String,
phone: String,
email: String,
streeAddress: String,
zipCode: String,
city: String,
companyName: String,
designation: String,
annualIncome: String) {
self.name = name
self.gender = gender
self.birthDate = birthDate
self.birthPlace = birthPlace
self.height = height
self.weight = weight
self.phone = phone
self.email = email
self.streeAddress = streeAddress
self.zipCode = zipCode
self.height = height
self.city = city
self.companyName = companyName
self.designation = designation
self.annualIncome = annualIncome
}
}
//This is function in Xcode-Playground which executes our test code
func main() {
let hitendra = Person(name: "Hitendra Solanki",
gender: "Male",
birthDate: "2nd Oct 1991",
birthPlace: "Gujarat, India",
height: "5.9 ft",
weight: "85kg",
phone: "+91 90333-71772",
email: "hitendra.developer@gmail.com",
streeAddress: "52nd Godrej Street",
zipCode: "380015",
city: "Ahmedabad",
companyName: "Fortune 500",
designation: "Software architect",
annualIncome: "45,000 USD")
//use of Person object
print("\(hitendra.name) works in \(hitendra.companyName) compay as a \(hitendra.designation).")
}
//call main to execute our test code in Xcode-Playground
main()
/* Console output:
Hitendra Solanki works in Fortune 500 compay as a Software architect.
*/
Tente executar o exemplo acima no playground, ele será executado com sucesso e fornecerá o resultado esperado. Logicamente está correto. Tente executar o exemplo acima no playground, ele será executado com êxito e fornecerá o resultado esperado. Logicamente correto.
Podemos melhorar o exemplo acima, superando os pontos abaixo. Podemos melhorar o exemplo acima superando os seguintes pontos.
-
Temos que passar os valores na ordem mencionada, não podemos reordenar a sequência dos parâmetros para melhorar a legibilidade. Devemos passar os valores na ordem acima, a sequência de parâmetros não pode ser reordenada para melhorar a legibilidade.
-
Temos que passar todos os valores, mesmo que não conheçamos alguns valores no momento da criação do objeto. Devemos passar todos os valores, mesmo que não conheçamos alguns valores ao criar o objeto.
Por exemplo Suponha que você precise criar um objeto da classe Person, mas a pessoa ainda está procurando emprego. Quando essa pessoa ingressar em alguma empresa só então teremos os detalhes do trabalho. Suponha que você precise criar um objeto da classe Pessoa, mas o objeto ainda está procurando trabalho. Quando essa pessoa ingressar em alguma empresa, só nós teremos os detalhes da vaga.
Solução:
Solução:
-
Crie grupos lógicos de propriedades relacionadas. Crie grupos lógicos de propriedades relacionadas.
-
Crie classes construtoras separadas para diferentes grupos de propriedades [ajuda na normalização de propriedades, isso é opcional. Criar classes geradoras separadas para diferentes grupos de atributos [ajuda na normalização de atributos, isso é opcional.
-
Recupere uma instância na etapa final. Uma instância é recuperada na etapa final.
Vamos simplificar isso com um exemplo, Vamos simplificar com um exemplo,
Já temos uma classe chamada Person no exemplo WithoutDesignPatternExample1.swift, na qual temos 14 propriedades. Se verificarmos atentamente todas as 14 propriedades, as propriedades terão 4 grupos lógicos. Por exemplo, já temos uma classe chamada Person sem designpatternexample1. Swift, temos 14 propriedades. Se examinarmos cuidadosamente todas as 14 propriedades, existem 4 grupos lógicos dessas propriedades.
-
Propriedades de dados pessoais Atributos de informações pessoais
-
Propriedades de detalhes de contato Propriedades de informações de contato
-
Propriedades de detalhes do endereço Propriedades de detalhes de endereço
-
Propriedades de detalhes da empresa Detalhes da empresa propriedades
Os padrões de design facetado e fluente juntos nos ajudam a superar os dois problemas mencionados acima. Os padrões de design Facetado e Fluente juntos nos ajudam a superar os dois problemas mencionados acima.
BuilderDesignPattern[Faceted+Fluent]Example1.swift:
//This is function in playground which executes our test code
func main() {
var hitendra = Person() //person with empty details
let personBuilder = PersonBuilder(person: hitendra)
hitendra = personBuilder
.personalInfo
.nameIs("Hitendra Solanki")
.genderIs("Male")
.bornOn("2nd Oct 1991")
.bornAt("Gujarat, India")
.havingHeight("5.9 ft")
.havingWeight("85 kg")
.contacts
.hasPhone("+91 90333-71772")
.hasEmail("hitendra.developer@gmail.com")
.lives
.at("52nd Godrej Street")
.inCity("Ahmedabad")
.withZipCode("380015")
.build()
//use of Person object
print("\(hitendra.name) has contact number \(hitendra.phone) and email \(hitendra.email)")
//later on when we have company details ready for the person
hitendra = personBuilder
.works
.asA("Software architect")
.inCompany("Fortune 500")
.hasAnnualEarning("45,000 USD")
.build()
//use of Person object with update info
print("\(hitendra.name) works in \(hitendra.companyName) compay as a \(hitendra.designation).")
}
//call main to execute our test code
main()
//Person class which only contains the details
class Person {
//personal details
var name: String = ""
var gender: String = ""
var birthDate: String = ""
var birthPlace: String = ""
var height: String = ""
var weight: String = ""
//contact details
var phone: String = ""
var email: String = ""
//address details
var streeAddress: String = ""
var zipCode: String = ""
var city: String = ""
//work details
var companyName: String = ""
var designation: String = ""
var annualIncome: String = ""
//empty constructor
init() { }
}
//PersonBuilder class helps to construct the person class instance
class PersonBuilder {
var person: Person
init(person: Person){
self.person = person
}
//personal details builder switching
var personalInfo: PersonPersonalDetailsBuilder {
return PersonPersonalDetailsBuilder(person: self.person)
}
//contact details builder switching
var contacts: PersonContactDetailsBuilder {
return PersonContactDetailsBuilder(person: self.person)
}
//address details builder switching
var lives: PersonAddressDetailsBuilder {
return PersonAddressDetailsBuilder(person: self.person)
}
//work details builder switching
var works: PersonCompanyDetailsBuilder {
return PersonCompanyDetailsBuilder(person: self.person)
}
func build() -> Person {
return self.person
}
}
//PersonPersonalDetailsBuilder: update personal details
class PersonPersonalDetailsBuilder: PersonBuilder {
func nameIs(_ name: String) -> Self {
self.person.name = name
return self
}
func genderIs(_ gender: String) -> Self {
self.person.gender = gender
return self
}
func bornOn(_ birthDate: String) -> Self {
self.person.birthDate = birthDate
return self
}
func bornAt(_ birthPlace: String) -> Self {
self.person.birthPlace = birthPlace
return self
}
func havingHeight(_ height: String) -> Self {
self.person.height = height
return self
}
func havingWeight(_ weight: String) -> Self {
self.person.weight = weight
return self
}
}
//PersonContactDetailsBuilder: update contact details
class PersonContactDetailsBuilder: PersonBuilder {
func hasPhone(_ phone: String) -> Self {
self.person.phone = phone
return self
}
func hasEmail(_ email: String) -> Self {
self.person.email = email
return self
}
}
//PersonAddressDetailsBuilder: update address details
class PersonAddressDetailsBuilder: PersonBuilder {
func at(_ streeAddress: String) -> Self {
self.person.streeAddress = streeAddress
return self
}
func withZipCode(_ zipCode: String) -> Self {
self.person.zipCode = zipCode
return self
}
func inCity(_ city: String) -> Self {
self.person.city = city
return self
}
}
//PersonCompanyDetailsBuilder: update company details
class PersonCompanyDetailsBuilder: PersonBuilder {
func inCompany(_ companyName: String) -> Self {
self.person.companyName = companyName
return self
}
func asA(_ designation: String) -> Self {
self.person.designation = designation
return self
}
func hasAnnualEarning(_ annualIncome: String) -> Self {
self.person.annualIncome = annualIncome
return self
}
}
/* Console output:
Hitendra Solanki has contact number +91 90333-71772 and email hitendra.developer@gmail.com
Hitendra Solanki works in Fortune 500 compay as a Software architect.
*/
No exemplo acima, separamos as responsabilidades da classe Person em diferentes classes. A classe Person agora contém apenas as propriedades de dados, enquanto criamos várias classes construtoras com responsabilidades de construir/atualizar o grupo relativo de propriedades. No exemplo acima, dividimos as responsabilidades da classe Person em diferentes classes. A classe Person agora contém apenas atributos de dados e criamos várias classes construtoras que são responsáveis por construir/atualizar grupos de atributos relacionados.Temos uma classe construtora base PersonBuilder e mais quatro classes construtoras derivadas chamadas PersonPersonalDetailsBuilder, PersonContactDetailsBuilder, PersonAddressDetailsBuilder e PersonCompanyDetailsBuilder. Temos uma classe de construtor básica PersonBuilder e quatro classes de construtor derivadas, nomeadamente PersonPersonalDetailsBuilder, PersonContactDetailsBuilder, PersonAddressDetailsBuilder e PersonCompanyDetailsBuilder.
A classe base PersonBuilder nos ajuda a alternar entre vários construtores a qualquer momento, enquanto outros quatro construtores derivados de PersonBuilder têm responsabilidades de atualizar propriedades relativas. A classe base PersonBuilder nos ajuda a alternar entre vários construtores a qualquer momento, enquanto os outros quatro construtores derivados de PersonBuilder são responsáveis por atualizar as propriedades relacionadas.
No exemplo acima, podemos ver claramente que a construção de um objeto Person é mais legível em comparação com nosso primeiro exemplo WithoutDesignPatternExample1.swift e também podemos atualizar o grupo de propriedades ou qualquer propriedade única a qualquer momento de uma maneira mais legível. No exemplo acima, podemos ver claramente que a estrutura do objeto Person é muito mais legível em comparação com o nosso primeiro exemplo.

No exemplo acima, observe que estamos retornando a própria instância do construtor após chamar cada método de atualização de propriedade. O que nos ajuda a escrever o encadeamento de vários métodos do mesmo construtor, em vez de escrever várias linhas separadamente. Este conceito é conhecido como padrão Fluente. No exemplo acima, observe que após chamar cada método de atualização de propriedade, retornamos a própria instância do gerador. Isso nos ajuda a escrever o encadeamento de vários métodos do mesmo gerador em vez de escrever várias linhas separadas. Este conceito é chamado de modo de coerência.
Benefícios:
Benefícios:
-
Inicialize facilmente um objeto de uma classe com muitas propriedades de uma maneira mais legível. Inicializa facilmente um objeto de uma classe com muitas propriedades, para melhor legibilidade.
-
Segue o princípio da responsabilidade única. Siga o princípio da responsabilidade única.
-
Inicialize o objeto ou atualize as propriedades em qualquer ordem conforme sua conveniência. Inicialize objetos ou atualize propriedades em qualquer ordem conforme sua conveniência.
Bônus:
Bônus:
Para tornar o padrão do construtor consistente em todo o projeto, você pode criar o protocolo conforme abaixo. Para tornar o padrão do gerador consistente em todo o seu projeto, você pode criar um protocolo como o seguinte.

Texto original: https://medium.com/flawless-app-stories/design-patterns-by-tutorials-the-power-of-oop-2e871b551cbe
What to read next
Want more posts about Translation?
Posts in the same category are usually the best next step for reading more on this topic.
View same categoryWant to keep following #Translation?
Tags are useful for related tools, specific problems, and similar troubleshooting notes.
View same tagWant to explore another direction?
If you are not sure what to read next, return to the homepage and start from categories, topics, or latest updates.
Back home