Elektrik Mühendisliği İlkeleri
Prototip Deseni Clone'ye kullanarak ve Ember'deki Ui Bileşenleri Değiştirin.js
Table of Contents
Prototip Desene ve Ember.js
Prototip Desen, mevcut bir örnekle yeni nesneler yaratmaktan biridir - nesne yaratımı pahalı olduğunda, farklı nesne türlerinin sayısı yüksek olduğunda, farklılıkları küçük, veya alt sınıf hiyerarşilerinin karmaşıklığını azaltmak için ihtiyacınız olduğunda.
Ember.js bağlamında, hırslı web uygulamaları oluşturmak için olgun bir çerçeve, Prototip Desen, UI bileşeni yönetimine uygulanabilir. Ember'in bileşeni sistemi zaten yeniden kullanılabilirlik ve encapsulation etrafında tasarlanmıştır, ancak uygulama büyüdükçe, geliştiriciler genellikle sadece birkaç özellikte farklı bir özellikte farklı olan birçok benzer bileşeni oluşturabilirsiniz - ancak kartpostal kuralları, farklı doğrulama kuralları ile girişler oluşturabilir.
Bu makale sizi Prototip Desenin arkasındaki teori aracılığıyla yürüyecek, bunu Ember.js'te beton kod örnekleriyle nasıl uygulayacağınızı göster, avantajlarını ve tuzaklarını tartışacak ve kullanım için kılavuzlar sağlayacaktır - veya kaçın - bu model kendi projelerinde.
Derinlikteki Prototip Deseni Anlayın
Prototip Desen, mülk delegasyonuna dayanmaktadır: 0) Özel bir değere sahiptir[Dönetici: 1 ), JavaScript'in kendisi için yereldir.Her JavaScript nesnesi, bir yapıda “yeni” aramamaktadır; bunun yerine, birFLT yöntemine sahiptir: bu, prototip üzerinde özel bir nesne ile aynı duruma gelir.[Dönetici).
Desendeki Anahtar Katılımcılar:
- [FONT:0)Prototype[[Dönetici: 1))[FONTD:2) işlemi ilan etti.
- [FONT:0)ConcretePrototype[Döntgen: 1))[Dönetici: 1) Gerçek nesne, genellikle kendi özelliklerini kopyalayarak.
- [FONT:0)Client[[Dönetici:0) – Prototipin kendisini klonlamasını isteyen kod.
Java veya C++ gibi dillerde, klonlama genellikle uygulama gerektirir.Dairede derin vs. sığ kopyaların dikkatli bir şekilde işlenmesi gerekir, çünkü nesneler zaten dinamik olarak daha basittir - ancak referans paylaşımı etrafında inceler de sunar.
Ember.js geliştiricileri için, bu modeli anlamak sadece akademik değil. Ember'in kendi nesne modeli, prototipden yapılmış olan mevcut mülk değerlerini korumak, sadece bir temel nesneden anlık olarak kullanılabilir. ancak,TELFLT:6) bir klondan daha fazla bir fabrikaya sahip değildir.
Prototip Deseni Ember.js Bileşenlerine Uygulayın
Ember'deki öğeler, kendi devletleri tarafından tanımlanan sınıfların örnekleridir veya eski ESDÜSÜSÜMÜZÜSÜMÜZÜSÜMÜZÜSÜMÜZÜSÜMÜZÜŞÜNÜŞÜNÜ KAYNAKLAR (İngÜŞÜNÜ ve ötesinde), bileşenler yerel JavaScript sınıfları tarafından desteklenir ve her örnek kendi durumu (argular, takip edilen özellikler) taşır.
Prototipleme Sınıfları Prototipleme
Varsayılan davranışı tanımlayan bir bileşen olduğunu düşünün (örneğin, bir olayı yangınlayan bir tıklama eylemi, varsayılan bir etiket “Submit”, varsayılan CSS sınıfı “btn”).
Bir yaklaşım Ember'in sınıf mirası kullanmak: 03. Ama miras, statik bir ebeveyn-çocuk ilişkisi yaratır. Prototip Desen daha dinamik bir yaklaşım sunar: “prototip” bir bileşeni (veya tüm varsayılan özellikleri ile düz bir nesne) ve özel ayarlarla yeni örnekler üretmek için kullanabilirsiniz.
İşte prototip kayıt olarak çalışan bir hizmet kullanarak basitleştirilmiş bir örnek:
// app/services/component-prototypes.js
import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
export default class ComponentPrototypesService extends Service {
@tracked prototypes = new Map();
registerPrototype(name, prototypeObject) {
this.prototypes.set(name, prototypeObject);
}
clonePrototype(name, overrides = {}) {
const prototype = this.prototypes.get(name);
if (!prototype) {
throw new Error(`Prototype '${name}' not found`);
}
// Create a shallow copy of the prototype properties
const clone = Object.assign({}, prototype, overrides);
return clone;
}
}
Sonra, uygulamanızda, bir temel düğme prototipi kayıt ediyorsunuz:
// app/initializers/register-prototypes.js
export function initialize(application) {
const service = application.lookup('service:component-prototypes');
service.registerPrototype('button', {
componentName: 'base-button',
args: {
text: 'Submit',
type: 'button',
action: 'defaultAction',
theme: 'primary',
},
});
}
Bir sil düğmesine ihtiyacınız olduğunda:
const deleteButtonConfig = service.clonePrototype('button', {
args: {
text: 'Delete',
theme: 'danger',
action: 'deleteRecord',
},
});
// Then render using
Bu yaklaşım, bileşen şablonundan yapılandırmayı ikiye katlar ve minimum kod ile birçok çeşit oluşturmanıza olanak sağlar.
Klonlama Kompozisyon (Runtime Cloning)
Zaten seçilmiş bir bileşen örneği hileli çünkü Ember bileşenlerinin yaşam döngüsü kancaları, iç devlet (parlanmış özellikler) ve DOM dernekleri vardır. Kullanıcının zaten (örneğin, bir form satır) ile etkileşime girdiği bir bileşeni tekrarlamanız gerekir, derin bir şekilde takip edilen durumu ve argümanları.
Pratik bir model, bileşenin argümanları ve iç durumu hakkında “snapshot” kullanmak, o zaman bu anlık görüntülerle yeni bir örnek inşa etmek. Ember'sİLFLT:16) yardımcı cihazı bir yapılandırma nesnesinden dinamik olarak kullanılabilir. Örneğin, [[FONTFLT:17|
// In a template
{{#each this.clonedConfigs as |config|}}
<component @name="base-button" @config={{config}} />
{{/each}}
JavaScript mantığı orijinal bileşeninin argümanlarını örnek olarak anlık görüntülerdi (yeni bir parça yeni bir yaşam döngüsüne sahip olacak), ancak bu, bileşenin mevcut görünümü ve davranışın bir kopyasını elde edersiniz.
Pratik Örnek: Bir Themed Düğme Ailesi İnşa Etmek
Düğme örneği tam, üretim hazır bir senaryoya genişletelim. Birden fazla düğme seçeneği ile bir tasarım sistemi inşa etmenizi varsayalım: birincil, ikincil, başarı, tehlike, uyarı, taslak ve bağlantı.Her bir değişken arka renkte, sınır, metin rengi, hover etkiler ve bazen davranışta (örneğin, bir “danger” düğmesine bir onay dialog gerektirebilir.
Prototip Desen olmadan, her biri yakın-identical şablonlarla yedi ayrı bileşen dosyaları yazabilirsiniz.modelle, bir tane ” bileşeni tanımlıyorsunuz ve sonra klonlanmış ve özelleştirilmiş bir yapılandırma nesnesi kullanabilirsiniz.
Adım 1: BaseButton Bitirme
Parça, tüm değişken parçaları içeren bir argümanı kabul eder.
// app/components/base-button.js
import Component from '@glimmer/component';
import { action } from '@ember/object';
export default class BaseButton extends Component {
get text() {
return this.args.config.text || 'Button';
}
get theme() {
return this.args.config.theme || 'primary';
}
get className() {
return `btn btn-${this.theme}`;
}
@action
handleClick() {
if (this.args.config.action) {
this.args.config.action.call(this);
}
}
}
{{! app/components/base-button.hbs }}
<button type="button" class={{this.className}} {{on "click" this.handleClick}} disabled={{@config.disabled}}>
{{this.text}}
{{#if @config.icon}}
<span class="icon">{{@config.icon}}</span>
{{/if}}
</button>
Adım 2: Prototip Cloning ile bir düğme Fabrikası hizmeti oluşturun
Basit bir nesne yerine, ortak özelleştirmeler için yöntemleri içeren bir İLFLT:26 kullanabiliriz.
// app/services/button-prototype.js
import Service from '@ember/service';
export default class ButtonPrototypeService extends Service {
constructor() {
super(...arguments);
this._registry = new Map();
this._registerDefaults();
}
_registerDefaults() {
const base = {
text: 'Submit',
theme: 'primary',
disabled: false,
icon: null,
action: null,
confirmation: null,
};
this._registry.set('button', { ...base });
}
registerVariant(name, overrides) {
const base = this._registry.get('button');
if (!base) throw new Error('Base button prototype not found');
const variant = { ...base, ...overrides };
this._registry.set(`button:${name}`, variant);
}
clone(name, customOverrides = {}) {
const prototype = this._registry.get(name);
if (!prototype) throw new Error(`Prototype '${name}' not found`);
return { ...prototype, ...customOverrides };
}
}
Adım 3: Register Variants
İlk birleştirici veya rotada:
this.buttonPrototype.registerVariant('danger', {
text: 'Delete',
theme: 'danger',
confirmation: 'Are you sure?',
action: () => alert('Deleted!'),
});
this.buttonPrototype.registerVariant('success', {
text: 'Save',
theme: 'success',
icon: 'check',
});
Adım 4: Bir Şablonda Kullanımı
<BaseButton @config={{this.buttonPrototype.clone 'button:danger'}} />
<BaseButton @config={{this.buttonPrototype.clone 'button' (hash text='Create New' theme='primary')}} />
Bu model plikasyonu azaltır ve yeni düğme çeşitlerini eklemek için önemsiz yapar - sadece overrides ile yeni bir prototip kayıt edin.
Deep Cloning vs. Haveber Cloning
Nested veri yapıları içeren nesneleri klonlarken (örneğin, nesneler dizileri), sığ ve derin kopyalar arasında karar vermeniz gerekir. A sığ kopya referansları kopyalar; klon hala aynı temel nesnelere işaret eder. derin bir kopya tamamen yeni nesneler recursive yaratır.
Ember'de, bileşen argümanları ([[DÜŞÜNÜCÜŞÜNÜŞÜŞÜNÜŞÜNÜŞÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜ
JavaScript'te derin klonlama yapmak için, you can useETHFLT:32} (Modern tarayıcılarda ve Node.js 17+) veya Lodash'sur'sur'sETHFLT:33 gibi bir kütüphane de derin kopya işlevselliği sağlar.
import { copy } from '@ember/object/internals';
const deepClone = copy(prototype, true); // true for deep
Ember proxy veya takip edilen özellikleri içeren nesneleri klonlama konusunda dikkatli olun - klonlama düzgün bir şekilde serileştirmeyebilir. prototip nesneleri basit, düz JavaScript nesneler (POJOs) Ember-specific reaktivite olmadan. klonlanmış yapılandırılabilir.
Ember'deki diğer Desenlerle Prototip Desenleri Karşılaştırmak
Geliştiriciler genellikle Ember'in yerleşik alt sınıf veya fabrika fonksiyonları yerine Prototip Deseni kullanmaları gerektiğini merak ederler.
Prototip vs. Sınıf Inheritance
Ember, sınıf mirası bileşenleri için desteklemektedir.You can writeFLT:37} ve override properties. Bu çalışır, ancak yeni sınıfların özelliklerini birleştiren bir düğmeye ihtiyacınız varsa (örneğin, küçük bir tehlike düğmesi), çok sayıda mirasa veya karışıma ihtiyacınız vardır, ki bu da diğer yandan, sabit bir hiyerarşi yaratır.
Prototip vs. Fabrika Deseni
Fabrika Deseni ayrıca nesne yaratımını da merkezileştiriyor, ancak genellikle her seferinde parametrelere dayanan yeni bir örnek döndürür, mevcut bir nesne klonlamaz.Farklılık ince: Bir fabrika Yaratılış mantığını zorlayabilir, bir prototip tabanlı yaklaşım depolarken, şablon verileri dışsal olarak geri döndürür (profilli Desen, temel şablonun kendisi çalıştırıldığında daha esnektir).
Prototip vs. Decorator Desen
Dekorasyon Deseni, yapısını değiştirmeden bir nesneye davranış ekler. Prototip Desen bir kopya yaratır ve sonra birleştirilebilirler: bir prototip klonlayabilir ve sonra ek davranışlarla mikser veya daha yüksek sipariş bileşenleri ile dekore edebilirsiniz.
Ember'deki Prototip Desen Kullanımının Avantajları.js
- [FONT=0)Redük Code Duplication:[Dönetici:[Dönetici:0)Redük Kodu Duplication:[Dönetici:[Dönetici: 1 ) Varsayılan davranışı ve bir kez ortaya çıkarmak, sonra klon ve düzeltme.
- [FONT:0]Consistency:[Dönetici:[Dönetici:0)[Dönetici:[Dönetici:[Dönetici: 0) Cloning, tüm elde edilen parçaların aynı temelden başladığını, kazara ayrılıkları ortadan kaldırmasını sağlar.
- [FONT:0)Runtime Flexability:[Dönetici:[Dönetici:0)[Dönetici:0)[Dönetici:[Dönetici:0)) Yeni prototipleri bir API veya kullanıcı tercihlerinden yükleyebileceğiniz ve hemen bileşenler oluşturmak için kullanabilirsiniz - gerekli yeniden inşa edilmemektedir.
- [FONT:0)Easier Unit Test:[Dönetici:[Dönetici:0)[Düzücü Birim Testi:[Dönetici:[Döncükler) Bilinen bir prototiple temel bileşeni test edin, sonra klonlama mantığı ayrı test edin.
- [FONT:0)Performance:[[Dönetici:[Dönetici:0)[[Dönlendirme:[Dönlendirme:[Dönlendirme:0)Eğer klonlama ucuzsa (sevcut verilerin kopyaları), özellikle sınıf hiyerarşisinden gelen bir zaman daha hızlı.
Potansiyel Pitfalls ve Desenten Kaçmak İçin Ne Zaman
- [FONT:0) Deep Copy Overhead:[Döneticileriniz büyük ihmal edilmiş nesneler içeriyorsa, derin klonlama pahalı olabilir. Güvenilir veri yapıları kullanmayı düşünün veya keşfedilmemiş parçaları paylaş.
- [FONT:0) ⁇ Edilebilir Devlet:[Dönetici:[Dönlendirme) Begonsuz devlet paylaşımına yol açar. Her zaman mutatemel nesneler için derin klonlama kullanın veya klonlamadan sonra asla yanlış tartışmalarınızı yapmamanızı sağlayın.
- [FONT:0) Dinamik Şablonlarda Komplexite:) Eğer ağır derecede doğrultsanız, bileşen şablonu büyük bir dev haline gelebilir.
- [FONT:0] Tüm Bileşenlerin Uygun Değil:[Dönetici:[Dönetici:0) Karmaşık iç devlet (örneğin, kendi geri dönüştürülmüş bir yığınla zengin bir metin editörü), yapılandırın tek başına yetersizdir.
- [FONT:0)Genellikle ilgili yorumlar:[Dönetici: 0,0) Eğer her küçük varyasyon için bir prototip oluştursanız, bazen şablonda basit bir koşullu olabilirsiniz.
Dış Kaynaklar ve Daha Fazla Okuma
JavaScript ve Ember'deki Prototip Deseni daha derin bir anlayış için aşağıdaki kaynakları düşünün:
- [FONT:0)Refaksiyon Guru: Prototip Desen) - Birden çok dilde diyagramlar ve kod örnekleri ile mükemmel bir açıklama.
- [FONT:0)Ember.js Bitirme Kılavuzu[[Dönetici: 1 ) - Ember'deki bileşenleri oluşturmak ve kullanmak için resmi belgeler.
- [[Dönetici:0)MDN: yapılandırılmışClone()[Döntilmiş: Modern JavaScript API'si derin klonlama için.
- [FONT:0)Ember Object Internals – kopya()) – Ember'in derin klonlama için kopya yardımı.
Sonuç: Prototip Deseni Ember Çalışma Akışına Bütünleştirmek
Prototip Desen, Ember.js geliştiricinin aracıkit'te çok yönlü bir araçtır, özellikle de UI bileşeninin modellerini yönetmek için bir varsayılan bileşeni yapılandırmayı prototip olarak depolamak ve aşırı kullanımla klonlamanız, tutarlılığı artırmak ve yüksek derecede yüksek bir çalışma süresi esnekliği elde edebilirsiniz.
Herhangi bir tasarım modeliyle, anahtar, Ember'in reaktif sistemi ve bileşeni ile modellemek için kullanılan küçük bir bileşen seti ile başlayın (amatons, kartlar, listeler). Güven kazanırken, modeli daha karmaşık senaryolara genişletebilirsiniz.Problep kalıbını Ember'in reaktif sistemi ve bileşeniyle birleştirerek, eklentileri değiştirmeye adapte eden basit, ölçeklenebilir bir UI mimarisi oluşturabilirsiniz.
Hedefin kendi iyiliği için bir model takip etmediğini unutmayın, ancak kodunuzu daha güvenli ve geliştirme sürecinizi daha verimli hale getirmek için.Kendinizi bir düzine dosyayı bir düzineye geçmişken, durun ve şunu sorun: “Bir prototip oluşturup klonlayabilir miyim?” cevap sizi daha temiz, daha zarif bir çözüme götürecektir.