鉴于以下FooService
:
scala> trait FooService {
| def go: Int
| }
defined trait FooService
还有一个MainService
,代表一种主要方法。
scala> trait MainService extends FooService {
| def f = go + 42
| }
defined trait MainService
FooService
可以有假(用于测试)和实际实现(例如命中数据库):
scala> object FakeService extends FooService {
| def go = 10
| }
defined object FakeService
scala> object RealService extends FooService {
| def go = 55 // in reality, let's say it hit the DB and got a value
| }
defined object RealService
在我看来,添加一个"跑步者" class / trait,即运行sbt run
将导致该类的执行,是可行的。它看起来像是:
scala> class Main extends MainService {
| override def go = RealService.go
| }
defined class Main
我也可以定义一个测试:
scala> class Test extends MainService {
| override def go = FakeService.go
| }
defined class Test
我不太确定这是定义真实与测试MainService
的惯用方法。请告诉我。
答案 0 :(得分:4)
您可以使用流行的蛋糕模式,也称为" Scala方式"做依赖注入。
Jon通过演练对此做了很好的blog post(他还列出了一些替代方案)。
首先,FooService
:
trait FooServiceComponent {
val fooService: FooService
trait FooService {
def go: Int
}
}
这就是说,我们需要两件事:1。实际对象,2。它的定义/实现。两者都命名在一起。尼斯。以下是Fake
和Real
版本:
trait FakeService extends FooServiceComponent {
class FakeService extends FooService {
def go = 10
}
}
trait RealService extends FooServiceComponent {
class RealService extends FooService {
def go = 55
}
}
现在,对于MainService
:
trait MainServiceComponent { this: FooServiceComponent =>
val mainService: MainService
class MainService extends FooService {
def f = go + 42
def go = fooService.go // using fooService
}
}
请注意自键入this: FooServiceComponent
,这是一种Scala方式,表示MainServiceComponent
依赖于FooServiceComponent
。如果您尝试在MainServiceComponent
中实例化FooServiceComponent
而不混合任何Test
,那么您将收到编译时错误。尼斯。 :)
现在,让我们创建具有不同特征的Main
和object Test extends MainServiceComponent with FakeService {
val mainService = new MainService()
val fooService = new FakeService()
}
object Main extends MainServiceComponent with RealService {
val mainService = new MainService()
val fooService = new RealService()
}
个对象:
FakeService
请注意,由于命名空间,Main
无法在println(Test.mainService.f) // -> 52
println(Main.mainService.f) // -> 97
中访问,因为它没有混入。很好。 :)还要注意你延迟任何类的实例化,直到这一点,这很方便,你可以很容易地使用注册表或模拟库在一个地方替换它们。
结果:
function upload_barang(){
$this->admin_model->login();
$this->admin_model->valid_product();
$config['upload_path'] = './produk/';
$config['allowed_types'] = 'jpg';
$config['max_size'] = '100';
$config['max_width'] = '400';
$config['max_height'] = '400';
$this->load->library('upload',$config);
$data['query'] = $this->db->get('kategori');
if($this->form_validation->run() == FALSE && ! $this->upload->do_upload()) {
$data['error'] = $this->upload->display_errors();
$data['success'] = '';
$this->load->view('backoffice/tambahbarang',$data);
} else {
$upload_data = $this->upload->data();
$data['error'] = '';
$data = array(
'idkategori' => $this->input->post('idkategori'),
'namabarang' => $this->input->post('nbarang'),
'image' => $upload_data['file_name'],
'status' => 1
);
$data_insert = $this->db->insert('barang',$data);
if($data_insert == TRUE) {
$data['query'] = $this->db->get('kategori');
$query = $this->db->get('barang');
$rows = $query->row();
$data['idbarang'] = $rows->idbarang;
$harga = array(
'idbarang' => $data['idbarang'],
'satuan' => $this->input->post('stcbarang'),
'harga' => $this->input->post('hbarang')
);
$this->db->insert('hargabarang',$harga);
$data['success'] = '<b>Barang Telah Ditambahkan</b>';
$this->load->view('backoffice/tambahbarang',$data);
} else {
$data['success'] = '<b>Barang Gagal Ditambahkan</b>';
$this->load->view('backoffice/tambahbarang',$data);
}
}
}
我希望这会有所帮助。